从GHC 7.6 文档:
[Y]你通常甚至不需要SPECIALIZE附注。当编译一个模块M时,GHC的优化器(带有-O)会自动考虑在M中声明的每个顶层重载函数,并且专门针对它在M中调用的不同类型。优化器还会考虑每个导入的INLINABLE重载函数,并专门针对它在M中被称为的不同类型
和
此外,给定一个函数f的SPECIALIZE pragma,GHC将自动为f调用的任何类重载函数创建专门化,如果它们与SPECIALIZE pragma在同一个模块中,或者它们是INLINABLE; 等等。
因此,GHC应该自动专门化一些标记为INLINABLE 无标注的大部分/全部(?)功能,如果使用明确的附注,则专门化是传递性的。我的问题是:汽车专业化传递?
具体来说,这是一个小例子:
Main.hs:import Data.Vector.Unboxed as Uimport Foomain = let y = Bar $ Qux $ U.replicate 11221184 0 :: Foo (Qux Int) (Bar (Qux ans)) = iterate (plus y) y !! 100 in putStr $ show $ foldl1' (*) ansFoo.hs:module Foo (Qux(..), Foo(..), plus) whereimport Data.Vector.Unboxed as Unewtype Qux r = Qux (Vector r)-- GHC inlines `plus` if I remove the bangs or the Baz constructodata Foo t = Bar !t | Baz !tinstance (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 + v2GHC专门调用plus,但并没有专门(+)的Qux Num杀死性能实例。
但是,一个明确的杂注
{-# SPECIALIZE plus :: Foo (Qux Int) -> Foo (Qux Int) -> Foo (Qux Int) #-}导致文档指出传递专业化,所以(+)是专门的,代码是30倍以上(都编译-O2)。这是预期的行为?我是否应该只希望(+)用一个明确的附注来传递?
相似问题