假设我想写两个 Typeclass。标题:
{-# LANGUAGE QuantifiedConstraints #-}
{-# LANGUAGE UndecidableInstances #-}
import Data.Complex
第一个类型类 ExClass 是这样定义的:
class (forall a. (Monoid (t a))) => ExClass t where
exFunc :: [t (Complex a)] -> t (Complex a)
exFunc = mconcat -- the actual function is more complicated
exFunc2 :: (RealFloat a) => t (Complex a) -> a
我将它定义为更高种类的类型类,因为它的一个函数的输出类型取决于其嵌套值的类型a
。我也希望有一个默认实现,但它涉及到MonoidexFunc
的假设。t a
现在我想为以下类型编写一个实例:
newtype ExType a = ExType a
ExType a
仅当Num a
为真时才为 Monoid:
instance (Num a) => Semigroup (ExType a) where
ExType a <> ExType b = ExType (a * b)
instance (Num a) => Monoid (ExType a) where
mempty = ExType 1
现在我继续为 定义类型类实例ExClass
,指定 的约束Num a
:
instance (forall a. Num a) => ExClass ExType where
exFunc2 (ExType a) = magnitude a
上面的代码将毫无问题地编译。但是,如果我尝试像这样使用已实现的功能:
x = ExType 2 :: ExType (Complex Double)
func = exFunc2 x
我收到以下投诉:
• No instance for (Num a) arising from a use of ‘exFunc2’
Possible fix: add (Num a) to the context of a quantified context
• In the expression: exFunc2 x
In an equation for ‘func’: func = exFunc2 x
当我使用不同的实例声明时也会发生这种情况:
instance (forall a. Monoid(ExType a)) => ExClass ExType where
exFunc2 (ExType a) = magnitude a
有没有办法让这个类型类工作?还是我根本不应该像这样构建我的程序?