我学习Haskell。我将命令发送到ghci::info Num
。
ghci> :info Num
class Num a where
(+) :: a -> a -> a
(*) :: a -> a -> a
(-) :: a -> a -> a
negate :: a -> a
abs :: a -> a
signum :: a -> a
fromInteger :: Integer -> a
-- Defined in `GHC.Num'
instance Num Integer -- Defined in `GHC.Num'
instance Num Int -- Defined in `GHC.Num'
instance Num Float -- Defined in `GHC.Float'
instance Num Double -- Defined in `GHC.Float'
我希望看到类似的内容:class (Eq a, Show a) => Num a
,但我看到class Num a where
。我很惊讶......好吧,我打开Hoogle并尝试查找Num
类类型的信息。我得到了this result。我在搜索结果的第一条记录中看到class (Eq a, Show a) => Num a
。但是当我打开消息来源时,我看到了:
-- | Basic numeric class.
--
-- Minimal complete definition: all except 'negate' or @(-)@
class Num a where
为什么我得到class Num a where
而不是class (Eq a, Show a) => Num a
?
答案 0 :(得分:13)
显示class (Eq a, Show a) => Num a
的黑客可能是一个错误,但Num a
确实没有理由要求Eq a
和Show a
。
答案 1 :(得分:10)
我认为Hoogle的搜索索引很老了。
您可以看到在Eq
的这些提交中,Show
和Num
超类已从ghc
中移除。
https://github.com/ghc/ghc/commit/0a40540e79223f38ee851c66eb377db9a1756e4b https://github.com/ghc/ghc/commit/817c4e19a4248b80f0af764d12721b1284b39e5a
所以我认为这就是Hoogle的搜索结果与Hackage的实际链接之间不一致的原因。
答案 2 :(得分:8)
这是一个Num
实例,您无法明智地定义Eq
或Show
实例 -
instance Num r => Num (a -> r) where
(f + g) a = f a + g a
(f - g) a = f a - g a
(f * g) a = f a * g a
abs f = abs . f
signum f = signum . f
fromInteger = const . fromInteger
这是一个稍微深奥的一个 -
data State s a = State { runState :: s -> (a, s) }
instance Functor (State s) where
fmap f h = State $ \s -> let (a, s') = runState h s in (f a, s')
instance Num a => Num (State s a) where
h + k = State $ \s -> let (a, s') = runState h s
(b, s'') = runState k s'
in (a + b, s'')
h * k = State $ \s -> let (a, s') = runState h s
(b, s'') = runState k s'
in (a * b, s'')
negate = fmap negate
abs = fmap abs
signum = fmap signum
fromInteger n = State $ \s -> (fromInteger n, s)
它具有不寻常的属性,即加法和乘法不可交换(因为两个参数中的每一个都可以任意修改状态,并且状态可以与返回的结果任意混合)但是否则它是{{的有效实例1}}。
数学侧注:
Num
类通常模拟称为rings的代数结构,它具有可交换加法和(不一定是可交换的)乘法,它满足一些兼容性规则在这种情况下,添加不是可交换的,因此它不能是一个环。它甚至不是near-semiring(这是一个删除了很多限制的环),因为它不符合分配律。这提出了一个问题 - 它是否遵守任何合理知名的代数结构的规律?
这两个都是更普遍现象的例子,可以使用Num
和Num
-
fmap
的实例
liftA2
这是我非常喜欢的事实。
答案 3 :(得分:3)
Num
是你基本可以添加和繁殖的东西。我认为(+)
应该是group,但specification没有提到它。
你能添加和乘法功能吗?当然可以,如果函数产生一个数字。
haskell中的函数没有Eq
和Show
实例,这就是Num
不需要这些约束的原因。
现在你也想要Ord
约束?复数是Num
s,但没有排序保留与实数相同的定律。