থেকে ডক্স GHC 7.6 জন্য:
[ওয়াই] আপনার প্রায়শই প্রথমে বিশেষ প্রগমা প্রয়োজন হয় না। মডিউল এম সংকলন করার সময়, জিএইচসি-র অপটিমাইজার (-ओ) স্বয়ংক্রিয়ভাবে এম-তে ঘোষিত প্রতিটি শীর্ষ-স্তরের ওভারলোডেড ফাংশনটি স্বয়ংক্রিয়ভাবে বিবেচনা করে এবং এটি এম-তে যে বিভিন্ন ধরণের বলা হয় তার জন্য বিশেষীকরণ করে The অপটিমাইজার প্রতিটি আমদানি করা INLINABLE ওভারলোডেড ফাংশনও বিবেচনা করে, এবং বিভিন্ন ধরণের জন্য এটি এম তে ডাকা হয় for
এবং
তদুপরি, একটি ফাংশনের জন্য একটি বিশেষ প্রগমা দেওয়া, জিএইচসি স্বয়ংক্রিয়ভাবে যে কোনও টাইপ-শ্রেণীর-ওভারলোডযুক্ত ক্রিয়াকলাপগুলির জন্য বিশেষায়নের তৈরি করবে, যদি তারা স্পেসিয়ালিজ প্রাগমা হিসাবে একই মডিউলে থাকে বা তারা অনন্য; এবং তাই, ট্রানজিটিভ।
সুতরাং জিএইচসির কিছুটা / বেশিরভাগ / সমস্ত (?) ফাংশন স্বয়ংক্রিয়ভাবে প্রগমা INLINABLE
ব্যতীত চিহ্নিত করা উচিত এবং যদি আমি স্পষ্টত প্রগমা ব্যবহার করি তবে বিশেষত্বটি ট্রানজিটিভ। আমার প্রশ্ন: অটো- স্পেশালাইজেশন কি ট্রানজিটিভ?
বিশেষত, এখানে একটি ছোট উদাহরণ রয়েছে:
Main.hs:
import Data.Vector.Unboxed as U
import Foo
main =
let y = Bar $ Qux $ U.replicate 11221184 0 :: Foo (Qux Int)
(Bar (Qux ans)) = iterate (plus y) y !! 100
in putStr $ show $ foldl1' (*) ans
Foo.hs:
module Foo (Qux(..), Foo(..), plus) where
import Data.Vector.Unboxed as U
newtype Qux r = Qux (Vector r)
-- GHC inlines `plus` if I remove the bangs or the Baz constructor
data Foo t = Bar !t
| Baz !t
instance (Num r, Unbox r) => Num (Qux r) where
{-# INLINABLE (+) #-}
(Qux x) + (Qux y) = Qux $ U.zipWith (+) x y
{-# INLINABLE plus #-}
plus :: (Num t) => (Foo t) -> (Foo t) -> (Foo t)
plus (Bar v1) (Bar v2) = Bar $ v1 + v2
জিএইচসি কলটিতে বিশেষীকরণ করেছে plus
, তবে সেই কর্মক্ষমতাটি হ্রাস করে এমন ক্ষেত্রে বিশেষীকরণ করে না ।(+)
Qux
Num
তবে, একটি সুস্পষ্ট প্রগমা
{-# SPECIALIZE plus :: Foo (Qux Int) -> Foo (Qux Int) -> Foo (Qux Int) #-}
দস্তাবেজগুলি যেমন নির্দেশ করে তেমনি ট্রানজিটিভ স্পেশালাইজেশনে ফলাফল , তাই (+)
বিশেষীকরণ করা হয় এবং কোডটি 30x দ্রুত (উভয়ই সংকলিত -O2
) হয়। এই প্রত্যাশিত আচরণ? আমার কি কেবল (+)
স্পষ্টত প্রগমা দিয়ে ট্রানজিটিভ বিশেষায়িত হওয়ার আশা করা উচিত?
হালনাগাদ
7.8.2 এর জন্য দস্তাবেজগুলি পরিবর্তন হয়নি, এবং আচরণও একই, তাই এই প্রশ্নটি এখনও প্রাসঙ্গিক।
plus
ছিল না INLINABLE এবং 2 হিসাবে চিহ্নিত) simonpj নির্দেশিত কিছু টিকেট কোড দিয়ে যাচ্ছে ইনলাইনিং ছিল, কিন্তু থেকে কোর আমার উদাহরণটি দেখায় যে কোনও ফাংশনই ইনলাইনড ছিল না (বিশেষত, আমি দ্বিতীয় Foo
নির্মাণকারী থেকে মুক্তি পেতে পারি না , অন্যথায় জিএইচসি ইনলাইনড স্টাফ)।
plus (Bar v1) = \(Bar v2)-> Bar $ v1 + v2
, যাতে এলএইচএস কল-সাইটে পুরোপুরি প্রয়োগ হয়? এটি কি অন্তর্ভুক্ত হয় এবং তারপরে স্পেশালাইজেশন লাথি দেয়?
plus
এই লিঙ্কগুলির কারণে আমার কাছে প্রথমে বিশেষভাবে পুরোপুরি প্রয়োগ করার জন্য কল ছিল , কিন্তু বাস্তবে আমি কম বিশেষীকরণ পেয়েছি: কলটিও বিশেষায়িত plus
ছিল না। এর জন্য আমার কোনও ব্যাখ্যা নেই, তবে অন্য একটি প্রশ্নের জন্য এটি ছেড়ে দেওয়ার ইচ্ছা ছিল বা আশা করি যে এটির উত্তর দিয়ে সমাধান হয়ে যাবে।