Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Haskell - fmap fmap doesn't work

I'm using GHCi (version 6.12.3) to play a bit with Haskell. I recently read about functors and applicative functors thought if you couldn't something similar to <*> of applicative functors be implemented only using functor's primitives. After some thinking I came up with fmap fmap which would have a (nearly) ideal type of

Functor f => f (a -> b) -> f (f a -> f b) or more generically

(Functor f1, Functor f2) => f1 (a -> b) -> f1 (f2 a -> f2 b)

I tried

let q = fmap fmap

I got the following error

<interactive>:1:8:
    Ambiguous type variable `f1' in the constraint:
      `Functor f1' arising from a use of `fmap' at <interactive>:1:8-16
    Probable fix: add a type signature that fixes these type variable(s)

<interactive>:1:13:
    Ambiguous type variable `f' in the constraint:
      `Functor f' arising from a use of `fmap' at <interactive>:1:13-16
    Probable fix: add a type signature that fixes these type variable(s)

Writing the above type signature as suggested didn't help. The craziest thing is when i typed :t fmap fmap I got an equivalent type as the above.

What am I doing wrong? Why does fmap fmap give a type error although GHCi finds a type for it?

like image 721
Mafi Avatar asked Apr 29 '11 21:04

Mafi


1 Answers

Looks like you're running into the monomorphism restriction.

Trying your example in GHCi with -XNoMonomorphismRestriction gives your expected result.

You can also subvert this by writing let f x = fmap fmap $ x. The monomorphism restriction only applies to top-level definitions which "look like" values, i.e. f = something, so introducing an explicit argument causes it not to apply anymore. It would also not apply if this was not at the top level (for example in a where clause). For more details, see the link.

like image 95
hammar Avatar answered Nov 15 '22 07:11

hammar