
{-# LANGUAGE RankNTypes #-}
newtype General = General { useGeneral :: forall a. Integral a => a -> Bool }
doesNotWork :: General doesNotWork = let g = even :: forall a. Integral a => a -> Bool b = specializeGeneral g in General g
doesWork :: General doesWork = let g = General even b = specializeGeneral (useGeneral g) in g
specializeGeneral :: (Int -> Bool) -> Bool specializeGeneral p = p 5
I was under the impression that one can always use a more general type where a more special type is needed. In `doesNotWork` above, despite the explicit Rank-2 type annotation, usage in `specializeGeneral` apparently makes the compiler infer the type of `g` to be (Int -> Bool) and complains that `a` can not me matched with `Bool`. What gets me is that the compiler error is at `General g`, so the compiler must have ignored my Rank-2 type annotation. Should it be allowed to do that?
Olaf
Hi Olaf,
This is the monomorphism restriction. g is a binding without a signature, so it gets specialized. The type annotation is part of
the
body of g, but if you want to generalize g it should be a separate declaration
let g :: forall ... g = ...
Oh, thanks! I should have suspected. But somehow I feel my type annotation should have circumvented the monomorphism restriction. So g = even is a pattern binding and therefore subject to monomorphism restriction, regardless of following type annotation? So thanks for teaching me that it is not irrelevant where to place a type annotation. To this day I believed that name = expression :: type and name :: type name = expression are equivalent because one is syntactic sugar for the other. Do the two give rise to different elements in the abstract syntax tree? Am I the only one who finds this odd? Which Haskell book should I have read to be aware of this? The Consequences part in Section 4.5.5 of the Haskell report mentions the distinction between function an pattern bindings, but is not clear about the position of the type annotation. It merely states "the user must be careful to affix these [pattern bindings] with type signatures to retain full overloading". Olaf