使用具有RankNTypes的函数组合时键入错误

时间:2015-10-23 00:41:48

标签: haskell existential-type

我对以下程序感到困惑。

{-# LANGUAGE RankNTypes #-}
newtype A a = A ( forall f. Applicative f => f a )

good :: a -> A a
good x = A $ pure $ x

bad  :: a -> A a
bad  x = A . pure $ x

尝试编译时,收到此错误消息,抱怨bad

Couldn't match type `f0 a'
               with `forall (f :: * -> *). Applicative f => f a'
Expected type: f0 a -> A a
  Actual type: (forall (f :: * -> *). Applicative f => f a) -> A a
Relevant bindings include
  x :: a (bound at huh.hs:8:6)
  bad :: a -> A a (bound at huh.hs:8:1)
In the first argument of `(.)', namely `A'
In the expression: A . pure

为什么函数good类型检查,而ghc拒绝接受函数bad?我能做些什么来使后一版本有效?据我所知,这两个例子应该是等价的。

1 个答案:

答案 0 :(得分:2)

正如在几条评论中所解释的那样,问题在于类型系统无法预测这是一种有效的类型,即使它是。在this answer中有一条提示,您可以明确指定.的类型来解决问题。

此代码段有效:

-- Type specialized composition
(.!) :: ((forall f. Applicative f => f b) -> c) ->
        (a -> (forall f. Applicative f => f b)) -> a -> c
(.!) f g x = f(g x)

-- Use the new version of composition
notBad  :: a -> A a
notBad  x = A .! pure $ x