你好,从Real World Haskell书中做的例子我遇到了这个例子,我无法理解它的意思和它是如何工作的:
instance Num a=>Num (SymbolicManip a)
在这种情况下,我应该转换为类似的东西:"对于Num类型的实例,SymbolicManip有一个约束关于它的类型领域a,是:a作为Num本身的一个实例"?有人可以告诉我,如果我解释正确或解释?
为什么instance Num (SymbolicManip a)不够?
-- The "operators" that we're going to support
data Op = Plus | Minus | Mul | Div | Pow
deriving (Eq, Show)
{- The core symbolic manipulation type -}
data SymbolicManip a =
Number a -- Simple number, such as 5
| Arith Op (SymbolicManip a) (SymbolicManip a)
deriving (Eq, Show)
{- SymbolicManip will be an instance of Num. Define how the Num
operations are handled over a SymbolicManip. This will implement things
like (+) for SymbolicManip. -}
instance Num a => Num (SymbolicManip a) where
a + b = Arith Plus a b
a - b = Arith Minus a b
a * b = Arith Mul a b
negate a = Arith Mul (Number (-1)) a
abs a = error "abs is unimplemented"
signum _ = error "signum is unimplemented"
fromInteger i = Number (fromInteger i)
Run Code Online (Sandbox Code Playgroud)
PS所有代码均来自本书(第 13 章 - 子章节 - 扩展示例 - 数值类型)
重要的是要看到a SymbolicManip a不能是一个实例Num而a不是NumSo 的实例,就像我们向函数添加约束一样,我们可以为类型类添加一个约束:
instance Num a => Num (SymbolicManip a) where
-- ^^^^^^^^ "As long as `a` is an instance of `Num`..."
-- ^^^^^^^^^^^^^^^^^^^^^ "...so is `SymbolicManip a`"
Run Code Online (Sandbox Code Playgroud)
我们必须包含Num a =>约束,因为在实现中,我们使用fromInteger生成该类型的成员a.这是不可避免的,就像Num为函数添加约束一样example a b = 2*a + b,即example :: Num a => a -> a -> a.
这是一个更简单的例子.考虑这种类型:
newtype Identity a = Identity a
Run Code Online (Sandbox Code Playgroud)
注意,a Identity a可以是一个实例Num,只要a它Num也是,所以,我们添加一个约束:
instance Num a => Num (Identity a) where
-- (...)
Run Code Online (Sandbox Code Playgroud)