我有些做作类型:多态约束
{-# LANGUAGE DeriveFunctor #-}
data T a = T a deriving (Functor)
...这类型是一些人为的类的实例:
class C t where
toInt :: t -> Int
instance C (T a) where
toInt _ = 0
我怎样才能表达函数约束T a
是所有a
的某个类的实例?
例如,请考虑以下功能:
f t = toInt $ fmap Left t
直觉上,我希望,因为toInt
作品上T a
所有a
上述功能的工作,但我无法表达,在类型。这不起作用:
f :: (Functor t, C (t a)) => t a -> Int
...因为当我们应用fmap
类型已经成为Either a b
。用我不能修复此:
f :: (Functor t, C (t (Either a b))) => t a -> Int
...因为b
并不代表普遍量化的变量。我也可以说:
f :: (Functor t, C (t x)) => t a -> Int
...或使用forall x
表明约束是适用于所有x
。
所以我的问题是,如果有一种方式来说约束是多态的一些类型的变量。
我认为像'C类T,其中toInt :: TA - > Int'将无法正常工作,你需要'C'是那种'* - >约束?种友多态会帮助吗? –
@ C.A.McCann我想到的具体类型构造函数是来自'pipes'的'Proxy',具体类是'Monad'。我为类似代理类型的类型分类实用程序函数,这就是为什么约束在那里。遵循你的建议,我会定义一个专门用于'Proxy'类型构造函数形式的'MonadP'类,并将其用作约束。缺点是,如果用户想要编写类似代理类型的代理实用程序函数多态,他们必须重新绑定符号才能使用“MonadP”。 –
你不能直接做,但可以模拟,就像罗马的答案一样。这里是相关的GHC票:http://hackage.haskell.org/trac/ghc/ticket/2893 – glaebhoerl