Haskell函数签名中的“等于”箭头

时间:2018-12-28 08:00:05

标签: haskell

我试图更好地理解手动指定Haskell函数签名,并且在这种情况下我不理解=>运算符。

这是我的例子:

Prelude> add a b = a + b 
Prelude> add 1 2
3

Haskell推断出此功能签名:

Prelude> :info add
add :: Num a => a -> a -> a 

这看起来很棒,因为如果我要手动定义它,我会做的:

add :: Int -> Int -> Int
add a b = a + b

因此,我知道推断类型更好,因为它允许:

Prelude> add 1.0 2.0
3.0
Prelude> add 1.0 2
3.0

但是我应该如何阅读

Num a => a -> a -> a

为什么不这样写,例如:

add :: Num -> Num -> Num

add :: Num a -> Num a -> Num a

这两个均失败:

add :: Num -> Num -> Num


[1 of 1] Compiling Main             ( my.hs, interpreted )

my.hs:4:8: error:
    • Expecting one more argument to ‘Num’
      Expected a type, but ‘Num’ has kind ‘* -> Constraint’
    • In the type signature: add :: Num -> Num -> Num
  |
4 | add :: Num -> Num -> Num
  |        ^^^

my.hs:4:15: error:
    • Expecting one more argument to ‘Num’
      Expected a type, but ‘Num’ has kind ‘* -> Constraint’
    • In the type signature: add :: Num -> Num -> Num
  |
4 | add :: Num -> Num -> Num
  |               ^^^

my.hs:4:22: error:
    • Expecting one more argument to ‘Num’
      Expected a type, but ‘Num’ has kind ‘* -> Constraint’
    • In the type signature: add :: Num -> Num -> Num
  |
4 | add :: Num -> Num -> Num
  |                      ^^^
Failed, no modules loaded.

add :: Num a -> Num a -> Num a

my.hs:4:8: error:
    • Expected a type, but ‘Num a’ has kind ‘Constraint’
    • In the type signature: add :: Num a -> Num a -> Num a
  |
4 | add :: Num a -> Num a -> Num a
  |        ^^^^^

my.hs:4:17: error:
    • Expected a type, but ‘Num a’ has kind ‘Constraint’
    • In the type signature: add :: Num a -> Num a -> Num a
  |
4 | add :: Num a -> Num a -> Num a
  |                 ^^^^^

my.hs:4:26: error:
    • Expected a type, but ‘Num a’ has kind ‘Constraint’
    • In the type signature: add :: Num a -> Num a -> Num a
  |
4 | add :: Num a -> Num a -> Num a
  |                          ^^^^^
Failed, no modules loaded.

所以我知道这是正确的语法。但是这个运算符“ =>”叫什么意思,即我将如何用英语阅读/发音上面的签名,以及如何在函数定义和其他地方查找其语法?

1 个答案:

答案 0 :(得分:4)

如果我们输入:

add :: Num a => a -> a -> a

=>是约束部分和签名本身之间的分隔符。

Num a意味着a必须属于Num类型类。

您可以具有多个约束(Num a, Show a) => a或不同类型的约束(Num a, Eq b) => a -> b -> c