首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >类型实例中的Typeclass约束

类型实例中的Typeclass约束
EN

Stack Overflow用户
提问于 2018-07-10 08:14:27
回答 2查看 145关注 0票数 2

你好,在做真实世界Haskell书中的例子时,我遇到了这个例子,我无法理解它的含义以及它是如何工作的:

instance Num a=>Num (SymbolicManip a)

在这种情况下,我应该翻译为:“对于SymbolicManip类型的Num实例,a类型的字段有一个约束,即:a是Num本身的一个实例”?有人能告诉我我是正确的解释还是解释?

为什么instance Num (SymbolicManip a)还不够?

代码语言:javascript
复制
-- 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)

所有代码都来自于这本书( subchapter-Extended 13章-数字类型)

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-07-10 08:21:17

重要的是要知道,如果没有SymbolicManip a也是Num的实例,那么a就不可能是Num的实例,因此,就像在函数中添加约束一样,我们可以向类型类型添加一个约束:

代码语言:javascript
复制
 instance Num a => Num (SymbolicManip a) where
 --       ^^^^^^^^ "As long as `a` is an instance of `Num`..."
 --                ^^^^^^^^^^^^^^^^^^^^^ "...so is `SymbolicManip a`"

我们必须包含Num a =>约束,因为在实现中,我们使用fromInteger生成类型为a的成员。这是unavoidable,,就像向函数example a b = 2*a + b (即example :: Num a => a -> a -> a )添加Num约束一样。

下面是一个简单的例子。考虑这种类型:

代码语言:javascript
复制
newtype Identity a = Identity a

注意,Identity a可以是Num的一个实例,只要a也是Num,那么我们就添加了一个约束:

代码语言:javascript
复制
instance Num a => Num (Identity a) where
-- (...)
票数 5
EN

Stack Overflow用户

发布于 2018-07-10 08:23:39

这意味着如果aNum的实例,那么SybolicManip a也是Num的实例。

所以如果你有:

代码语言:javascript
复制
x :: SymbolicManip Integer
y :: SymbolicManip Integer

然后,您可以编写x+y,而不需要定义它的含义。但是,如果您尝试添加两个SymbolicManip String值,您将得到一个类型错误,因为String不是Num的一个实例。

如果您查看实例,您将看到negatefromInteger都使用Num的特性。因此,如果去掉约束,编译器就会出现错误,无法推断aNum的一个实例。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51260266

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档