我玩弄面包车Laarhoven镜头,跑进其中类型检查器拒绝一个良好的输入功能的ETA-降低形式的问题:
{-# LANGUAGE RankNTypes #-}
import Control.Applicative
type Lens c a = forall f . Functor f => (a -> f a) -> (c -> f c)
getWith :: (a -> b) -> ((a -> Const b a) -> (c -> Const b c)) -> (c -> b)
getWith f l = getConst . l (Const . f)
get :: Lens c a -> c -> a
get lens = getWith id lens
上述类型的检查,但如果我ETA-减少get
来
get :: Lens c a -> c -> a
get = getWith id
然后,GHC(7.4.2)抱怨说,
Couldn't match expected type `Lens c a'
with actual type `(a0 -> Const b0 a0) -> c0 -> Const b0 c0'
Expected type: Lens c a -> c -> a
Actual type: ((a0 -> Const b0 a0) -> c0 -> Const b0 c0)
-> c0 -> b0
In the return type of a call of `getWith'
In the expression: getWith id
我可以理解,如果该功能没有显式类型签名然后ETA-减少与单态的限制可能会混淆类型推断,尤其是当我们面对的是更高级别类型的组合,但在这种情况下,我不肯定发生了什么事。
是什么原因导致GHC拒绝ETA还原形式,这是在GHC的错误/限制或更高级别类型的一些根本问题?