为什么`(\ x y-> x + y)@Integer会失败,而`(+)@ Integer`会成功?

时间:2018-09-03 04:40:52

标签: haskell types

考虑:

λ :type (+) @Integer
(+) @Integer :: Integer -> Integer -> Integer




λ :type (\x y -> x + y) @Integer
...
...error...
...Cannot apply expression...
...

λ f = (+)
λ :type f @Integer
...
...error...
...Cannot apply expression...
...

λ g = \x y -> x + y
λ :type g @Integer
...
...error...
...Cannot apply expression...
...

λ h x y = x + y
λ :type h @Integer
...
...error...
...Cannot apply expression...
...

同时:

λ :type (+)
... :: Num a => a -> a -> a

λ :type (\x y -> x + y)
... :: Num a => a -> a -> a

λ :type f
... :: Num a => a -> a -> a

λ :type g
... :: Num a => a -> a -> a

λ :type h
... :: Num a => a -> a -> a

因此,即使这些对象的类型没有区别,它们对于类型应用程序也看起来是不同的。

  • 为什么?
  • 我缺少明显的东西吗?
  • 这是一个错误吗?
  • 这是功能吗?
  • 这是糟糕的语言设计吗?
  • 这是很棒的语言设计吗?

1 个答案:

答案 0 :(得分:7)

在大多数情况下,仅当存在显式类型签名时才可以应用类型应用程序。引用GHC文件:

  

如果函数是标识符(常见情况),则仅在为标识符提供类型签名后,才认为其类型是已知的。

     

为什么?

我猜设计的存在是因为当您拥有显式签名时,类型变量的顺序已得到很好的定义。

  

我缺少明显的东西吗?

由您决定上述内容有多明显。您可以挖掘文档和设计讨论的思想,以查看对话的演变,但是当严格按照顺序执行类型应用程序时,参数的顺序似乎是一个问题。

  

这是一个错误吗?

我不这么认为。也许是lambda案。

  

这是功能吗?

只要一致性好就可以。

  

这是糟糕的语言设计吗?   这是很棒的语言设计吗?

也许更好的语言设计是在没有歧义的情况下允许简单的示例(例如您的示例)工作(类型实参顺序由于只有一个类型实参而隐含了)。