使用GHC 8.0,我可以编写一个模糊函数,它在类型签名的主要部分中未提及的某些类型上重载,然后使用显式类型应用程序调用它:
{-# LANGUAGE ScopedTypeVariables, RankNTypes,
AllowAmbiguousTypes, TypeApplications, TypeFamilies #-}
showRead :: forall t . (Read t, Show t) => String -> String
showRead x = show (read x :: t)
showReadInt = showRead @Int
Run Code Online (Sandbox Code Playgroud)
我想使用SPECIALIZEpragma来强制showReadfor的特化Int(我的实际代码在不同的模块中有实际的调用站点).但是,正常SPECIALIZE语法基于编写类型签名的主要部分,例如:
{-# SPECIALIZE showRead :: String -> String #-}
Run Code Online (Sandbox Code Playgroud)
并且在这种情况下,不允许我指定t应该是什么,并且可预测地给出关于它是模糊的错误.
我尝试使用等式约束:
{-# SPECIALISE showRead :: forall t . (Read t, Show t, t ~ Int) => String -> String #-}
Run Code Online (Sandbox Code Playgroud)
但那只是给出了错误:
Run Code Online (Sandbox Code Playgroud)• Could not deduce (Read t0) a SPECIALISE pragma for ‘showRead’ from the context: (Read t, Show t, t ~ Int) bound by the type signature for: showRead :: (Read t, Show t, t ~ Int) => String -> String at foo.hs:4:1-76 The type variable ‘t0’ is ambiguous
有什么方法可以做到这一点吗?当然我可以使用a Proxy,但是不要使用闪亮的新方法而感到羞耻.