[haskell-cafe] Monad and kinds

wren ng thornton wren at freegeek.org
Wed Sep 3 23:29:48 EDT 2008


Ramin wrote:
> Hello, I'm new here, but in the short time I have known Haskell, I can 
> already say it's my favorite computer language.
> 
> Except for monads, and no matter how many tutorials I read, I find the 
> only kind of monad I can write is the monad that I copied and pasted 
> from the tutorial, i.e. I still don't get it even though I thought I 
> understood the tutorial, and I'm stuck using monads others have already 
> written.
> 
> My project is this: I am writing a mini-database of sorts. I thought I 
> would make a query a monad, so I could chain multiple queries together 
> using the "do" notation, and run more complex queries on the list in one 
> shot. The query itself is stateful because it contains information that 
> changes as the database is traversed. The query may also make updates to 
> the records. I got the program to work perfectly using purely functional 
> techniques, but complex queries resulted in that stair-step looking 
> code. So I thought this would be the perfect opportunity to try my hand 
> at monads.
> 
> The query monad I wrote looks something like this (much simplified):
>    data Query state rec = Query !(state, rec)

A minor point but, that strictness annotation doesn't help you very much 
since tuples are lazy in their arguments. That declaration has the same 
strictness properties as:

     data Query state rec = Query state rec

The only difference is that your version gives you the "free" ability to 
  convert from a (Query s r) to a (s,r). The "free" is in quotes because 
either there's a cost in indirection to access the state and rec fields, 
or you've told GHC to optimize the tuple away in which case there's a 
cost in reconstructing the tuple when demanded.[1] Sometimes there's a 
reason to use a type like this, but generally it's not what was intended.

If you want the datatype to be strict in state and rec, then you should 
add strictness annotations to those fields directly:

     data Query state rec = Query !state !rec


[1] That is, when a tuple _really_ is demanded. GHC does a good job of 
replacing tuples with unboxed-tuples when optimizations are turned on. 
In these cases the code isn't really asking for a tuple so one needn't 
be reconstructed.

-- 
Live well,
~wren


More information about the Haskell-Cafe mailing list