Search code examples
haskellio-monad

Create haskell IO wrapper


In the GHC manual section on FFI, it is stated that the programmer can use newtype to create a wrapper monad around the IO monad and use it in place of the IO monad when calling foreign code. (GHC manual)

So far, I have:

newtype PGm a = PGm (IO a)
instance Monad PGm where
   (>>=) a b = ...
   (>>)  a b = ...
   return a  = PGm (return a) --I think
   fail a    = PGm (fail a)   --I think

I'm at a loss regarding how to implement (>>=) and (>>).


Solution

  • You just unwrap and rewrap each operation. The hard part is figuring out where the unwrapping and rewrapping goes:

    newtype PGm a = PGm (IO a)
    instance Monad PGm where
       (>>=) (PGm a) b = PGm (a >>= (unPGm . b))
         where
           unPGm (PGm x) = x
       (>>)  (PGm a) (PGm b) = a >> b
       return a  = PGm (return a)
       fail a    = PGm (fail a)
    

    However, this won't quite be enough, as Haskell requires instances for Functor and Applicative before a Monad instance may be defined. An easier solution would be to put the {-# LANGUAGE GeneralizedNewtypeDeriving #-} at the top of your file (or enable :set -XGeneralizedNewtypeDeriving in GHCi), which lets you do this;

    newtype PGm a = PGm (IO a) deriving (Functor, Applicative, Monad)
    

    The idea is that if you enable this extension, GHC will be smart enough to automatically derive newtype instances from their 'base' ones.