What is fmap doing here without explicitly declaring the method?

One exercise in the real world of Haskell, ch. 24, will ask to introduce a shell of rigor around Control.Concurrent.MVar

. I'm doing this, as suggested in the book, with a shell newtype


, to guarantee that evaluate

applies to all the arguments passed to functions such as newMVar

and putMVar


Now one of the functions for wrapping is mkWeakMVar

, which type is MVar a -> IO () -> IO (Weak (MVar a))

. Assuming my constructors MVarS

implement strictness, I figured that for mkWeakMVar

just putting s MVarS

instead of my own MVar

. So I wrote the following:

import           Control.Concurrent.MVar
import           System.Mem.Weak

instance Functor Weak

newtype MVarS a = MVarS (MVar a)

mkWeakMVarS :: MVarS a -> IO () -> IO (Weak (MVarS a))
mkWeakMVarS (MVarS mv) x = (fmap . fmap) MVarS (mkWeakMVar mv x)


This works, although GHCi warns that Functor Weak

there is no explicit method declaration for fmap

. But this intrigued me. What does fmap

work in this case?


source to share

1 answer

While the above code will validate, GHC will crash when trying to evaluate a value that requires a call to a missing implementation fmap

. It will look something like this:

*** Exception: /Users/tel/tmp/SO.hs:31:10-18: 
    No instance nor default method for class operation GHC.Base.fmap


Since this is a fairly catastrophic and completely preventable runtime error, it should serve as proof of importance -Wall




All Articles