Haskell($)是一个神奇的算子?

时间:2013-12-27 06:11:15

标签: haskell

说我有以下功能:

infixr 0 <|

{-# INLINE (<|) #-}
(<|) :: (a -> b) -> a -> b
f <| x = f x

foo :: a -> (forall b. b -> b) -> a
foo x f = f x

以下内容未进行类型检查:

ghci> foo 3 <| id

Couldn't match expected type `forall b. b -> b'
            with actual type `a0 -> a0'
In the second argument of `(<|)', namely `id'
In the expression: f 3 <| id
In an equation for `it': it = f 3 <| id

但是,foo 3 $ id

(据我所知)(&lt; |)的定义与($)的定义相同。我几乎从基础库源中删除了定义,并将($)的每个实例都更改为(&lt; |)。编译魔术?

1 个答案:

答案 0 :(得分:69)

是的,($)周围有少量的编译器魔法来处理impredicative类型。引入它是因为每个人都希望

runST $ do
  foo
  bar
  baz

到typecheck,但它不能正常。有关详细信息,请参阅here(搜索runST),此email和此email。缺点是,类型检查器中实际上有一个特殊规则专门用于($),这使得它能够解决不可预知类型的常见情况。