One of the exercises in Real World Haskell, ch. 24, asks to implement a strictness wrapper around Control.Concurrent.MVar
. I am doing this, as suggested in the book, by using a newtype
MVarS
wrapper to ensure that evaluate
is applied to whatever arguments get passed to functions such as newMVar
and putMVar
.
Now, one of the functions to wrap is mkWeakMVar
, whose type is MVar a -> IO () -> IO (Weak (MVar a))
. Assuming that my MVarS
builder functions implement strictness, I reasoned that for mkWeakMVar
it would suffice to put MVarS
in place of its MVar
s. 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 appears to work, even though GHCi warns that there is no explicit method declaration of fmap
for Functor Weak
. But it leaves me intrigued. What makes fmap
work in this case?