【发布时间】:2015-10-23 11:37:53
【问题描述】:
我对以下程序感到困惑。
{-# 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?我该怎么做才能使后一个版本正常工作?据我所知,这两个例子应该是等价的。
【问题讨论】:
-
简而言之:Haskell 的类型系统是可预测的,这意味着它不会实例化具有多态类型的类型变量(带有
foralls 的类型变量)。为了让bad进行类型检查,类型检查器需要用forall (f :: * -> *). Applicative f => f a实例化一些类型变量。但是,即使您打开-XImpredictiveTypes,您仍然需要在pure上添加类型注释。 -
@user2407038,predicAtive 和 impredicAtive。
-
永远不要使用
ImpredicativeTypes,除非有一天它真的被修复了。