Wrapping IO, part 1

I’ve many times heard that Haskell can be used to prevent certain kind of programmer mistakes. In a presentation on Darcs it was explained how GADTs (especially phantom types) are used in Darcs to make sure that operations on patches follow certain rules. Another way, and at least it sounds easier, is to limit the available functions by running code in some sort of container. This being Haskell, that container is often a monad. I’ve really never seen this presentedi, so I thought I’d try to do it, and indeed it turns out to be very simple.

I started with a data type:

newtype HideIO a = HideIO { runHideIO :: IO a }

which I then made into a Monad in order to make it easy to work with:

instance Monad HideIO where
    return = HideIO . return
 
    (>>=) m f = HideIO $ runHideIO m >>= runHideIO . f

Then I can create an IO function that are allowed in the HideIO monad:

hioPutStrLn = HideIO . putStrLn

In ghci I can then do the following:

> runHideIO $ hioPutStrLn "Hello, World!"
Hello, World!

But I can’t do much else.

  1. Most probably due do my weak searching-fu than anything else.[back]
Share

5 Comments

  1. Pingback: therning.org/ magnus » Blog Archive » Wrapping IO, part 2

  2. Please check the ‘jail’ package on Hackage for another example of this kind of trickery.

  3. You can derive the monad instance like this:

    {-# LANGUAGE GeneralizedNewtypeDeriving #-}
    
    newtype HideIO a = HideIO { runHideIO :: IO a }
        deriving(Monad)
    
  4. Pingback: therning.org/ magnus » Blog Archive » Strachey, referential transparency, Haskell

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>