[英]Could not deduce (Eq a) from (Num a) or from (Floating a). But Can deduce (Eq a) from (Integral a). Why?
我正在阅读一个haskell教程(非常好地了解一下haskell),我正在玩这本基于本书其中一个函数编写的代码。
reverseNum :: (Num a) => a -> a
reverseNum 123 = 321
reverseNum x = 0
和ghci告诉我它不能从(Num a)推导出(Eq a)。
所以我将第一行更改为此
reverseNum :: (Integral a) => a -> a
它起作用了。 这很奇怪,因为我认为你是Num类型类的一部分,你也需要成为Eq的一部分。
我尝试了另外一件事来满足我的好奇心并将前两行更改为此
reverseNum :: (Floating a) => a -> a
reverseNum 1.0 = 0.1
它给了我同样的错误。
我知道你可以通过做一些像reverseNum :: (Num a, Eq a) ...
这样的东西来解决这个问题reverseNum :: (Num a, Eq a) ...
但我想知道为什么Integral是唯一一个可以推导出Eq的东西。 这是为什么?
PS我对haskell真的很新......温柔:)
因为这是前奏中Num
的定义:
class Num a where
...
而Integral
的定义要求类型为Real
和Enum
:
class (Real a, Enum a) => Integral a where
...
Real
意味着Num
和Ord
......
class (Num a, Ord a) => Real a where
...
而Ord
自然会暗示Eq
:
class Eq a => Ord a where
...
这一行意味着为了使某些东西实现Ord
,它还必须实现Eq
。 或者我们可以说Ord
是Eq
的子类。 无论如何...
总结是Num
不是Eq
的子类,但Integral
是Eq
的子类。
您可以想象以无法实现Eq
方式实现Num
。
newtype Sequence = Sequence (Integer -> Integer)
instance Num Sequence where
(Sequence x) + (Sequence y) = Sequence $ \pt -> x pt + y pt
(Sequence x) - (Sequence y) = Sequence $ \pt -> x pt - y pt
(Sequence x) * (Sequence y) = Sequence $ \pt -> x pt * y pt
negate (Sequence x) = Sequence $ \pt -> -pt
abs (Sequence x) = Sequence $ \pt -> abs pt
signum (Sequence x) = Sequence $ \pt -> signum pt
fromInteger = Sequence . const
-- Ignore the fact that you'd implement these methods using Applicative.
这里, Sequence
是表示所有可计算序列的类型。 你不能以任何合理的方式实现Eq
,因为序列是无限长的!
instance Eq Sequence where
-- This will never return True, ever.
(Sequence x) == (Sequence y) =
and [x pt == y pt | pt <- [0..]] &&
and [x pt == y pt | pt <- [-1,-2..]]
因此, Num
不是Eq
的子类是有道理的,因为有一些有用的类型可以实现Num
而不是Eq
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.