[英]Typeclass constraint inside typeclass instance
你好,从Real World Haskell书中做例子,我遇到过这个例子,我无法理解它的含义以及它是如何工作的:
instance Num a=>Num (SymbolicManip a)
在这种情况下,我应该转换为类似于:“对于类型为SymbolicManip
Num实例,对于其类型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)
PS所有代码均来自本书( 第 13 章 - 子章节 - 扩展示例 - 数值类型)
地看到,这是重要的SymbolicManip a
不能被实例Num
无a
也作为一个实例Num
所以,就像当我们添加约束的功能,我们可以添加一个约束到一个类型类:
instance Num a => Num (SymbolicManip a) where
-- ^^^^^^^^ "As long as `a` is an instance of `Num`..."
-- ^^^^^^^^^^^^^^^^^^^^^ "...so is `SymbolicManip a`"
我们必须包含Num a =>
约束,因为在实现中,我们使用fromInteger
来生成类型a
成员。 这是不可避免的 ,就像向函数example ab = 2*a + b
添加Num
约束,即example :: Num a => a -> a -> a
。
这是一个更简单的例子。 考虑这种类型:
newtype Identity a = Identity a
请注意, Identity a
可以是Num
的实例,只要a
也是Num
,因此,我们添加一个约束:
instance Num a => Num (Identity a) where
-- (...)
这意味着如果a
是Num
的实例,则SybolicManip a
也是Num
的实例。
所以如果你有:
x :: SymbolicManip Integer
y :: SymbolicManip Integer
然后你可以编写x+y
而无需定义它的含义。 但是,如果您尝试添加两个SymbolicManip String
值,则会出现类型错误,因为String
不是Num
的实例。
如果查看实例,您将看到negate
和fromInteger
都使用Num
功能。 因此,如果您取出约束,那么编译器会给出关于无法推断出a
是Num
实例的错误。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.