咖喱(==)如何运作?

时间:2014-04-22 01:35:58

标签: haskell types ghci currying

我理解:

  

(==):: Eq a => a - > a - >布尔

应用程序的示例可能是(==)2 2,结果为True。

那:

  

uncurry(==):: Eq b => (b,b) - >布尔。

应用程序示例可能是uncurry(==)(2,2),结果为True。

但我不理解和想象一个例子:

  

咖喱(==)::( Eq a,Eq b)=> a - > b - > (a,b) - >布尔

任何帮助?

谢谢,
圣塞瓦斯蒂安

2 个答案:

答案 0 :(得分:9)

==可用于元组,即您可以编写(a1, b1) == (a2, b2)

在这种情况下,==的类型专门用于(Eq a, Eq b) => (a, b) -> (a,b) -> Bool

如果您现在将curry应用于该类型,则会获得(Eq a, Eq b) => a -> b -> (a, b) -> Bool

答案 1 :(得分:8)

curry的定义是:

curry :: ((a, b) -> c) -> a -> b -> c
curry f = \x y -> f (x, y)

如果我们将其替换为:

\x y z -> (curry (==) x y) z
\x y z -> ((==) (x, y)) z    -- Function application
\x y z -> (==) (x, y) z      -- Remove parentheses (function application is left associative in Haskell, so they are unnecessary here)
\x y z -> (x, y) == z        -- Convert to infix

我们可以立即告诉z也必须是某种元组,否则最后一行不会进行类型检查,因为==的两个参数必须具有相同的类型。

当我们查看Eq的元组实例的定义时,我们找到了

instance (Eq a, Eq b) => Eq (a, b) where
  (x, y) == (x', y') = (x == x') && (y == y')

(这并未在标准库的源代码中详细说明,它实际上使用"独立派生"机制自动派生(Eq a, Eq b) => (a, b)类型的实例。代码等同于派生的内容。)

因此,在这种情况下,我们可以将==视为具有类型

(==) :: (Eq a, Eq b) => (a, b) -> (a, b) -> Bool

xy都必须包含Eq个实例的类型,但它们不一定必须是{em>相同的实例{ {1}}。例如,如果我们有Eq12怎么办?这是两种不同的类型,但我们仍然可以使用我们的函数,因为它们都是"abc"Eq的实例(此表达式类型检查并评估为(\x y z -> (x, y) == z) (12, "abc") (30, "cd"))。