[Haskell-cafe] Re: Software architecture

Ertugrul Soeylemez es at ertes.de
Wed Aug 4 13:21:56 EDT 2010

Charles-Pierre Astolfi <cpa at crans.org> wrote:

> I'm searching for software designs in Haskell ; for example, I have a
> pretty good ideo of how I would arrange my modules/classes (in
> ocaml/(java/c++)) and how they would all fit together to create, say,
> a website aspirator. But I don't have any clue of the right way to do
> it with Haskell.
> I don't need a solution for this example, I'd just like to see how to
> manage non-trivial code. I haven't found any pointers on the
> interwebs.

This really depends on the concept you use to solve your problem.  In
most programming languages the glue is ready-made and tells you, how to
structure your program.  In Haskell you make your own glue.

For example, I use monads heavily and the logical parts of my program
are monad transformers.  The program itself is the stack of those.
Using type classes the individual transformers can communicate with each

  newtype GameT m a    = GT (StateT GameConfig m a)
  newtype TextureT m a = TT (StateT TextureConfig m a)
  newtype OpenGLT m a  = GLT (IdentityT m a)
  newtype SDLT m a     = SDLT (ReaderT SDLConfig m a)

  type MyAppT = GameT (TextureT (OpenGLT SDLT))

  game :: MyAppT IO ()

Another important type of glue in modern software programming is
concurrency.  Split your program into a number of subprograms (threads).
This is very well supported in Haskell:

  logVar <- newEmptyMVar
  let logStr   = putMVar logVar
  let logStrLn = putMVar logVar >=> const (putChar '\n')

  forkIO . forever $ takeMVar logVar >>= hPutStrLn stderr

When using other concepts, usually by using a library, use the glue of
that particular concept/library.  For example, if you use Yampa to model
a reactive system, your individual program parts could become signal

  fire :: SF Particle Particle
  snow :: SF Particle Particle

If your current problem is a Parser, your split it into subparsers.  For
example to parse HTML you definitely want to parse tags and entities.
To parse tags you want to parse attribute/value pairs.  Use the
composability features of monads to do this:

  tag       :: Parser Tag
  attribute :: Parser (ByteString, ByteString)
  entity    :: Parser Entity

The possibilities are endless.  You get the idea when writing actual


nightmare = unsafePerformIO (getWrongWife >>= sex)

More information about the Haskell-Cafe mailing list