Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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 (>>).

like image 766
Ed Behn Avatar asked Jan 26 '23 16:01

Ed Behn


1 Answers

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.

like image 132
bradrn Avatar answered Feb 05 '23 10:02

bradrn