我有一个包含"添加"操作的简单类
class (Eq a, Show a, Read a) => Group a where
add :: a -> a -> a
Run Code Online (Sandbox Code Playgroud)
我创建了一个名为"Z5"的新数据类型,其中包含一个构造函数参数,namly为int值:
data Z5 = Z5 Int deriving (Eq, Read, Show)
Run Code Online (Sandbox Code Playgroud)
数据类型的实例化如下所示:
instance Group (Z5) where
add x y = x+y
Run Code Online (Sandbox Code Playgroud)
问题是我收到错误消息:
No instance for (Num Z5) arising from a use of `+'
Possible fix: add an instance declaration for (Num Z5)
Run Code Online (Sandbox Code Playgroud)
我试过了
instance (Num Z5) => Group (Z5) where
add x y = x+y
Run Code Online (Sandbox Code Playgroud)
但然后错误信息是:
Non type-variable argument in the constraint: Num Z5
(Use -XFlexibleContexts to permit this)
In the context: (Num Z5)
While checking an instance declaration
In the instance declaration for `Group (Z5)'
Run Code Online (Sandbox Code Playgroud)
这个错误很简单: No instance for (Num Z5) arising from a use of `+'.你需要一个'Num'实例Z5.你有几个选择:
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
newtype Z5 = Z5 Int deriving (Eq, Read, Show, Num)
Run Code Online (Sandbox Code Playgroud)
这会Num为您的类型创建一个与其相同的实例Int.或者,您可以手动编写实例,如果您不希望它与实例相同Num.
instance Num Z5 where
(Z5 a) + (Z5 b) = Z5 (a + b + 5) -- you can do whatever you like here
Run Code Online (Sandbox Code Playgroud)
写约束C T在哪里C是一个类型类并且T是一个单形类型总是没有意义 ; 这将是真的,在这种情况下你不需要编写约束,或者它将是false,在这种情况下它将不会编译.
更一般地说,任何实例Num都是一个数学组,所以你可以写:
-- This newtype is defined in Data.Monoid
newtype Sum a = Sum a
instance Num a => Group (Sum a) where
add (Sum a) (Sum b) = Sum (a + b)
identity = Sum 0
invert (Sum x) = Sum (-x)
Run Code Online (Sandbox Code Playgroud)
然后你可以做以下事情:
>add ((Sum 4) :: Sum Z5) ((Sum 5) :: Sum Z5)
Sum {getSum = Z5 9}
Run Code Online (Sandbox Code Playgroud)