我认为参数化意味着它可以永远帮助专门化一个自由类型变量(即没有类约束的变量),就像函数
:: Maybe a -> Bool
一样。在 ghc 的背景下是否有任何情况可能实际上对我有所帮助?
(部分答案,但我还是想分享。)
我尝试专门研究 GADT 消除函数,看看 GHC 如何处理它。听起来很疯狂,但我很好奇。
data T a where
A :: Int -> T Int
B :: String -> T String
{-# SPECIALIZE foo :: T Int -> Int #-}
foo :: T a -> Int
foo (A i) = i
foo (B s) = length s
编译器对此略有抱怨:
warning: SPECIALISE pragma for non-overloaded function `foo'
|
| {-# SPECIALIZE foo :: T Int -> Int #-}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
不过,生成的 Core 显示了我希望看到的内容:专门的形式。
foo :: forall a. T a -> Int
foo
= \ (@a_aPp) (ds_dZc :: T a_aPp) ->
case ds_dZc of {
A co_aPq [Dmd=A] i_auj -> i_auj;
B co_aPs [Dmd=A] s_auk ->
case GHC.List.$wlenAcc @Char s_auk 0# of ww2_a1Ld { __DEFAULT ->
GHC.Types.I# ww2_a1Ld
}
}
Main.foo_$sfoo :: T Int -> Int
Main.foo_$sfoo
= \ (ds_dZc :: T Int) ->
case ds_dZc of { A co_aPq [Dmd=A] i_auj -> i_auj }
------ Local rules for imported ids --------
"SPEC foo" forall. foo @Int = Main.foo_$sfoo
这个有用吗?我不知道。这是真正的优化吗?或许。尽管如此,一些重写规则正在生成,指向简化的代码,因此这可能反过来会触发更严重的程序中的一些优化。