等同于'。'和' $'

时间:2016-11-14 09:35:03

标签: haskell types syntax

我有一个表达式:

gcastWith p1 $
gcastWith p2 $
e

这没关系。现在我试图将其重写为:

((gcastWith p1) .
 (gcastWith p2)) $
e

它不起作用(没有进行类型检查)。然而,这有效:

((gcastWith p1) .
 (gcastWith p2)) -- note I removed the dollar
e

我是否遗漏了有关$.如何运作的明显内容?

1 个答案:

答案 0 :(得分:7)

我猜它是由类型推断如何工作引起的一些限制。在基本的Hindley-Milner类型中,如

f :: (forall a. G a) -> T

是被禁止的。 GHC Haskell允许它们(启用了合适的扩展),但仍然使用HM限制,要求类型变量永远不能实例化为多类型。

这会导致一些意外:f e类型检查,但f $ e失败,因为$类型的类型变量应该实例化为多元类型。

e :: forall a. G a
f :: (forall a. G a) -> T
f e :: T

($) :: (b -> c) -> b -> c

Type checking ($) f e:

       b ~ (forall a. G a)   -- forbidden polytype!
       c ~ T

由于f $ e在Haskell中非常非常,并且我们真的希望runST $ do ....之类的东西能够正常工作,所以GHC开发人员为{{{{}}添加了一个特殊情况的输入规则1}}。基本上,完全应用后,$的输入类似于f $ e

目前f e的打字系统中没有这种特殊情况。这可能会在f . g . h $ e正常工作时失败。