使用 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
我想使用一个
SPECIALIZE
指令来强制特化showRead
函数的Int
参数(在我的实际代码中,调用点在另一个模块中)。然而,正常的SPECIALIZE
语法是基于编写类型签名的主要部分,例如:{-# SPECIALIZE showRead :: String -> String #-}
在这种情况下,我无法指定t
应该是什么,这很容易导致出现歧义的错误。
我尝试使用等式约束:
{-# SPECIALISE showRead :: forall t . (Read t, Show t, t ~ Int) => String -> String #-}
但这只是给出了错误信息:
• 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
有没有什么方法可以做到这一点?当然,我可以使用代理
,但不使用这种新的方式似乎是一种浪费。
RULES showRead @Int = showReadInt
这样的东西。 - chi