[Haskell-cafe] Problem with types

Erik Hesselink hesselink at gmail.com
Fri Aug 19 14:30:04 CEST 2011


On Fri, Aug 19, 2011 at 14:06, Anupam Jain <ajnsit at gmail.com> wrote:
> Hi all,
> Suppose I have a compound data type -
> data M o = M (String,o)
> Now, I can define a function that works for ALL M irrespective of o. For
> example -
> f :: M o -> M o
> f (M (s,o)) = M (s++"!", o)
> I can also use this function in an expression, applying it to different
> types without problem -
> p = (m1',m2') where
>   m1 = M ("1", ())
>   m2 = M ("2", True)
>   m1' = f m1
>   m2' = f m2
> Main*> p
> (M ("1!",()),M ("2!",True))
> However, if I try to parameterise over the function 'f' it does not work!  -
> p f = (m1',m2') where
>   m1 = M ("1", ())
>   m2 = M ("2", True)
>   m1' = f m1
>   m2' = f m2
> It doesn't even typecheck, producing the error - "Couldn't match expected
> type 'Bool' with actual type '()'"
> Is there a particular reason for this? How can I define a function like 'p'
> within Haskell?

If you write down the type for 'p', you get something like this:

p :: (forall a. M a -> M a) -> (M b, M b)

That is, the type variable 'a' isn't top level, but is forall'ed in
the function you pass. This is called a rank 2 type, and it cannot be
inferred automatically by GHC. You have to specify it yourself, and
turn on the Rank2Types or RankNTypes extension.

Erik



More information about the Haskell-Cafe mailing list