为什么可以用"Just (+)"创造价值?
Why can you create a value with "Just (+)"?
目前我正在学习 Haskell 并且一直在将类型实例化为类型类。我其实不明白,为什么可以用 Just (+)
.
创建 Maybe a
类型的值
这对我来说很奇怪的问题是,Maybe 类型被定义为 Eq
类型类的一个实例(参见 Haskell source) and that if you derive an instance for a type, all the fields of the value / data constructors of that type must be also an instance of the Eq
typeclass (here)。
考虑到这些知识,以下代码不应该是可编译或可执行的,因为函数不是 Eq
类型类的一部分:
let a = Just (+)
let b = Just (-)
但 GHCi 实际上执行了代码而没有抛出错误消息。如果您然后尝试比较这两个值(这也不应该是可能的),解释器会出现以下错误消息:
a == b
<interactive>:24:1: error:
* No instance for (Eq (Integer -> Integer -> Integer))
arising from a use of `=='
(maybe you haven't applied a function to enough arguments?)
* In the expression: a == b
In an equation for `it': it = a == b
如果您创建自己的 Maybe a
类型,也会出现此问题。
Maybe
的 Eq
实例最终看起来像这样(也就是说,deriving (Eq)
基本上被重写成这样):
instance (Eq a) => Eq (Maybe a) where
...
这可以理解为如果 a
是Eq
的成员,那么也是Maybe a
。所以做一个 Maybe (Int -> Int)
或你有什么是完全没问题的,如果它的参数不是,它就不会是 Eq
。
从编译器的角度来看,一种在操作上更有帮助的思考方式:要解决 Eq (Maybe a)
约束,解决 Eq a
约束就足够了。所以当我们说
a == b
编译器尝试解决 Eq (Maybe (Integer -> Integer -> Integer))
。它使用 Maybe
实例将问题缩减为 Eq (Integer -> Integer -> Integer)
,然后在无能为力时放弃。这就是为什么您看到错误消息抱怨 Eq (Integer -> Integer -> Integer)
没有实例,而不是提及 Maybe
.
目前我正在学习 Haskell 并且一直在将类型实例化为类型类。我其实不明白,为什么可以用 Just (+)
.
Maybe a
类型的值
这对我来说很奇怪的问题是,Maybe 类型被定义为 Eq
类型类的一个实例(参见 Haskell source) and that if you derive an instance for a type, all the fields of the value / data constructors of that type must be also an instance of the Eq
typeclass (here)。
考虑到这些知识,以下代码不应该是可编译或可执行的,因为函数不是 Eq
类型类的一部分:
let a = Just (+)
let b = Just (-)
但 GHCi 实际上执行了代码而没有抛出错误消息。如果您然后尝试比较这两个值(这也不应该是可能的),解释器会出现以下错误消息:
a == b
<interactive>:24:1: error:
* No instance for (Eq (Integer -> Integer -> Integer))
arising from a use of `=='
(maybe you haven't applied a function to enough arguments?)
* In the expression: a == b
In an equation for `it': it = a == b
如果您创建自己的 Maybe a
类型,也会出现此问题。
Maybe
的 Eq
实例最终看起来像这样(也就是说,deriving (Eq)
基本上被重写成这样):
instance (Eq a) => Eq (Maybe a) where
...
这可以理解为如果 a
是Eq
的成员,那么也是Maybe a
。所以做一个 Maybe (Int -> Int)
或你有什么是完全没问题的,如果它的参数不是,它就不会是 Eq
。
从编译器的角度来看,一种在操作上更有帮助的思考方式:要解决 Eq (Maybe a)
约束,解决 Eq a
约束就足够了。所以当我们说
a == b
编译器尝试解决 Eq (Maybe (Integer -> Integer -> Integer))
。它使用 Maybe
实例将问题缩减为 Eq (Integer -> Integer -> Integer)
,然后在无能为力时放弃。这就是为什么您看到错误消息抱怨 Eq (Integer -> Integer -> Integer)
没有实例,而不是提及 Maybe
.