考虑:
λ :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
因此,即使这些对象的类型没有区别,它们对于类型应用程序也看起来是不同的。
答案 0 :(得分:7)
在大多数情况下,仅当存在显式类型签名时才可以应用类型应用程序。引用GHC文件:
如果函数是标识符(常见情况),则仅在为标识符提供类型签名后,才认为其类型是已知的。
为什么?
我猜设计的存在是因为当您拥有显式签名时,类型变量的顺序已得到很好的定义。
我缺少明显的东西吗?
由您决定上述内容有多明显。您可以挖掘文档和设计讨论的思想,以查看对话的演变,但是当严格按照顺序执行类型应用程序时,参数的顺序似乎是一个问题。
这是一个错误吗?
我不这么认为。也许是lambda案。
这是功能吗?
只要一致性好就可以。
这是糟糕的语言设计吗? 这是很棒的语言设计吗?
也许更好的语言设计是在没有歧义的情况下允许简单的示例(例如您的示例)工作(类型实参顺序由于只有一个类型实参而隐含了)。