为什么我得到"班级Num a where"而不是"类(Eq a,Show a)=> Num a"?

时间:2014-12-19 07:36:40

标签: haskell ghci

我学习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

4 个答案:

答案 0 :(得分:13)

显示class (Eq a, Show a) => Num a的黑客可能是一个错误,但Num a确实没有理由要求Eq aShow a

答案 1 :(得分:10)

我认为Hoogle的搜索索引很老了。

您可以看到在Eq的这些提交中,ShowNum超类已从ghc中移除。

https://github.com/ghc/ghc/commit/0a40540e79223f38ee851c66eb377db9a1756e4b https://github.com/ghc/ghc/commit/817c4e19a4248b80f0af764d12721b1284b39e5a

所以我认为这就是Hoogle的搜索结果与Hackage的实际链接之间不一致的原因。

答案 2 :(得分:8)

这是一个Num实例,您无法明智地定义EqShow实例 -

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(这是一个删除了很多限制的环),因为它不符合分配律。这提出了一个问题 - 它是否遵守任何合理知名的代数结构的规律?

这两个都是更普遍现象的例子,可以使用NumNum -

将任何应用程序提升为fmap的实例
liftA2

这是我非常喜欢的事实。

答案 3 :(得分:3)

Num是你基本可以添加和繁殖的东西。我认为(+)应该是group,但specification没有提到它。

你能添加和乘法功能吗?当然可以,如果函数产生一个数字。

haskell中的函数没有EqShow实例,这就是Num不需要这些约束的原因。

现在你也想要Ord约束?复数是Num s,但没有排序保留与实数相同的定律。