haskell - 类型类实例内的类型类约束
问题描述
你好,在做 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)
PS所有代码都来自本书(第13章-子章-扩展示例-数字类型)
解决方案
重要的是要看到 aSymbolicManip a
不能是 So 的实例,也Num
不能a
是 So 的实例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
。这是不可避免的,就像Num
给函数添加约束一样example a b = 2*a + b
,即example :: Num a => a -> a -> a
。
这是一个更简单的例子。考虑这种类型:
newtype Identity a = Identity a
注意 anIdentity a
可以是 的实例Num
,只要a
aNum
也是,所以,我们添加一个约束:
instance Num a => Num (Identity a) where
-- (...)
推荐阅读
- calculator - 带有 Python 的 TI 84 Plus CE 无法以度数处理复杂的极坐标形式
- json - 配置服务不允许将规则上传到 AWS Config
- arrays - 第二次后从数组中删除所有内容\n
- python - 如何以递归方式将数字总和打印到n?
- for-loop - for 循环是否遍历 Lua 和 Love2d 中的空表?
- testing - 为什么我不能在 DW 测试中测试不为零且介于 -1 和 1 之间的自相关?
- mysql - 往返中的多个航班号 - MySQL
- ios - @Published 属性内模型更新时的 SwiftUI 触发功能
- python - 之间有什么不同。和 () 在 python
- git - 在不删除文件的情况下撤消未提交的 Git 更改 - 我错误地添加了我的计算机文件,我需要将其撤消