How can eta-reduction of a well typed function result in a type error?

荒凉一梦 提交于 2019-12-03 23:11:57

I'd say that the reason isn't in the η-reduction itself, the problem is that with RankNTypes you lose principal types and type inference.

The problem with type inference with higher-order ranks is when inferring the type of λx.M to obey the rule

     Γ, x:σ |- M:ρ
----------------------
  Γ |- λx:σ.M : σ→ρ

we don't know what type σ we should choose for x. In the case of Hindley-Milner type system, we limit ourselves to type-quantifier-free types for x and the inference is possible, but not with arbitrary ranked types.

So even with RankNTypes, when the compiler encounters a term without explicit type information, it resorts to Hindley-Milner and infers its rank-1 principal type. However, in your case the type you need for getWith id is rank-2 and so compiler can't infer it by itself.

Your explicit case

get lens = getWith id lens

corresponds to the situation where the type of x is already given explicitly λ(x:σ).Mx. The compiler knows the type of lens before type-checking getWith id lens.

In the reduced case

get = getWith id

the compiler has to infer the type of getWidth id on it's own, so it sticks with Hindley-Milner and infers the inadequate rank-1 type.

Actually it's quite straight-forward: GHC infers the types per expression, then starts to unify them across =. This works always fine when there are only rank-1-types around, because the most polymorphic one is chosen (that's well-defined); so any unification that's possible at all will succeed.

But it will not choose a more general rank-2-type even if that would be possible, so getWith id is inferred to be ((a -> Const a a) -> c -> Const a c) -> (c -> a) rather than (forall f . Functor f => (a -> f a) -> c -> f c) -> (c -> a). I suppose if GHC did do such stuff, traditional rank-1 type inference wouldn't work at all anymore. Or it would just never terminate, because there doesn't exist one well-defined most polymorphic rank-n type.

That doesn't explain why it can't see from get's signature that it needs to choose rank-2 here, but presumably there is a good reason for that as well.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!