Greg Weng recently asked on the Google+ Haskell page a question that newcomers to the Haskell programming language may ask: **What is an intuitive structure to construct a new Haskell program?**

A Google employee, Gregory Collins, responded with a refreshingly clear and simple suggestion:

TL;DR —

- Identify
*datatypes* - Identify
*Functor, Applicative, Alternative*structures - Life begins in
`main`

in the*IO Monad* - Stick to plain old
*IO*whenever possible - Lift to
*ReaderT*or*StateT*if need be - Refactor into
*pure*functions whenever possible - Do no underestimate power of simple higher-order functions from the base library
- Use
`undefined`

to stub out parts of a program to make it typecheck

Start by modeling the problem in the data domain. Identify the

datatypesthe program will need. What algebraic properties do they have? For example, if I can identify that a piece of data forms a Monoid, that opens several new options for guiding the design of the implementation — it means that you can aggregate a collection of these objects in parallel, for instance. The same thing goes for identifying Functor, Applicative, Alternative, etc structures.Once you know roughly what the inputs and outputs will be, and have modeled those types, start thinking about the

typeof the implementation. Every program starts with`main`

, and beginslife in the IO monad. Optionally, depending on what your program looks like, you may want tolift your computationinto some other monad. For example:ReaderTif your program has a global read-only state that should be available everywhere,StateTif you’re using a side-effecting process to mutate or grow a piece of data, or create your own custom monad here.But stick to

plain old IOwhere possible. The rest of the implementation process is a game of pushing as much of the program as possible intopure functions(they are much easier to test), and breaking problems down into small pieces of structure using the“standard toolbox”. It’s amazing how many computations are expressible usingsome combination of map/fold/filter/unfold/concat/scanletc….I will often

stub outparts of the program I know I will need later with`undefined`

just so that I can get a skeleton version of the program to typecheck.

All credit goes to Gregory Collins, the author of the awesome new io-streams library for I/O using streams.