Haskwhal

Missteps of a Narwhal Calf

Previous Entry Add to Memories Share Next Entry
liftIO and a Formal Haskell Learning Curve
king, avatar, owl, ozten, austin
ozten
I’ve come to know Control.Monad.Trans and liftIO for the first time.

I was trying to glue together Database.HDBC results and a Happstack.Server Response. My method’s which wouldn’t compile looked like

currentWeight :: ServerPartT IO Response
currentWeight = let conn = connectMySQL defaultMySQLConnectInfo { mysqlHost = host, mysqlDatabase = database, mysqlUser = username, mysqlPassword = password, mysqlUnixSocket = unixSocket}
                -- this works...
                --in return $ toResponse "f"
                -- but not this..
                in (currentStat conn) >>= showStats
                where
                  showStats :: Stats -> ServerPartT IO Response
                  showStats stats = return $ toResponse $ show stats

The function currentStat retrieves a row from the database and creates a Stats piece of data.

I got some help on #haskell from ksf and Twey. I now understand that I needed to “lift” my expressions of type IO into the ServerPartT monad. liftIO was the recommended function.

It makes sense now, but I didn’t know you could “stack contexts” like this.

There was also some discussion of fmap, <$>, etc... but it was all a bit much for me at this point. There are so many advanced features to the language, I think it’s tough to give newbies advice. It’s seems easy to bake in lots of advanced features instead of the most basic, brain dead example, so that they will see the core of the answer and can then later “rework” it as they learn Applicative, combinators, partially applied functions, etc.


One role that RWH plays, but that I think could be improved upon, is to have a Formal Haskell Learning Curve. It would be a series of “levels” in understanding the Haskell language. At beginner level I you study the syntax for declaring functions, data types, how to run your code, and part of the Prelude, recursion, etc. Level II you learn the IO monad, etc at higher levels it begins to branch. At level 4 you understand stacking monads, and a bunch of other stuff I don’t know yet :) Then when people are helping you they can try to stay on your level in the explanation.
Haskell Levels

We do this intuitively already when we teach someone a topic. With a formal learning curve, we can say... don’t tackle HDBC until your a level 3 and don’t mess with Happstack until your a level 4, etc.


They also pointed me to the Typeclassopedia, which I am reading now. This is good supplementary material, but covers way to many “levels” and steepens the learning curve.

W00t! I’ve got data being displayed in my browser via MySQL...
currentWeight :: ServerPartT IO Response
currentWeight = connectDb >>= (\conn ->
                    liftIO (currentStat conn) >>= showStats)
                where
                  connectDb = liftIO $ connectMySQL defaultMySQLConnectInfo { mysqlHost = host, mysqlDatabase = database, mysqlUser = username, mysqlPassword = password, mysqlUnixSocket = unixSocket}
                  showStats :: Stats -> ServerPartT IO Response
                  showStats stats = return $ toResponse $ show stats

The key here was lifting the connection and lifting my results from the database each time, before using the >>= function.

You are viewing ozten