[haskell-cafe] Monad and kinds

Ramin ramin.honary at gmail.com
Tue Sep 2 09:34:41 EDT 2008


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)

Where "state" is the type of state, so a query can contain any 
information relevant to the search and can be updated as the search 
progresses.
Then, "rec" is the type of records in the database, which isn't 
determined inside the database module, so I can't just declare "rec" to 
be of any type I choose.

But I just cannot write the instance declaration for my Query data type 
no matter what I try. If I write:
    instance Monad Query where
        return (initState, someRecord) = Query (initState, someRecord)
        {- code for (>>=) -}
GHC gives an error, "Expected kind `* -> *', but `Scanlist_ctrl' has 
kind `* -> * -> *' ". If I try this:
    instance Monad (Query state) where
        return (initState, someRecord) = Query (initState, someRecord)
        {- code for (>>=) -}
GHC give an error, "Occurs check: cannot construct the infinite type: a 
= (s, a) when trying to generalise the type inferred for `return' ".

I get the sense I am trying to shove a square peg into a round hole. I 
was thinking of trying some other things, like implementing the monad in 
a higher-level module where I knew the type of the records I would be 
using, but I don't like being told where to implement things. I also 
thought of trying to re-write my query algorithm to somehow use 
"Control.Monad.State.Strict" instead of my own query type, but then I 
wouldn't get to write my own monad!

Though the information given in this e-mail is limited, is there anyone 
who can clearly see there is something about monads that I just don't 
get and tell me what it is?

Anyone who took the time to read this, I am very appreciative.
    Ramin Honary


More information about the Haskell-Cafe mailing list