Missteps of a Narwhal Calf

Reading about hlint
king, avatar, owl, ozten, austin
Via Fatvat's take on HLint I learned about HLint and Neil Mitchell's post on the tool.

I haven't spent much time with it, but it seems like a good coding mentor for the intermediate Haskell programmer. As a noob, some of the feedback I'm afraid to accept, such as the changes that push it towards point free form, whereas I'm still clinging to my explicit parameters.

Haskell has many cool development tools, the more I read about the ecosystem.

hello world in CGI FastCGI and Happstack FastCGI
king, avatar, owl, ozten, austin
Just as a sanity check for Help! Can you run Happstack as a CGI? I made sure your Haskell CGI and FastCGI setup is working.


-- ghc --make -o CgiPlay.cgi CgiPlay.hs 
import Network.CGI

cgiMain :: CGI CGIResult
cgiMain = output "Hello World!"

main :: IO ()
main = runCGI (handleErrors cgiMain)


-- ghc -package fastcgi -threaded --make -o FCgiPlay.fcgi FCgiPlay.hs 
import Control.Concurrent
import System.Posix.Process (getProcessID)

import Network.FastCGI

test :: CGI CGIResult
test = do setHeader "Content-type" "text/plain"
          pid <- liftIO getProcessID
          threadId <- liftIO myThreadId
          let tid = concat $ drop 1 $ words $ show threadId
          output $ unlines [ "Process ID: " ++ show pid,
                             "Thread ID:  " ++ tid]

main = runFastCGIConcurrent' forkIO 10 test

Happstack on FastCGI

import Happstack.Server.FastCGI
import Happstack.Server.SimpleHTTP (askRq, getData, RqData, ToMessage)
import Happstack.Server (look, fromData, FromData, simpleHTTP, Conf(..), toResponse, ServerPartT)

simpleCGI :: (ToMessage a) => ServerPartT IO a -> IO ()
simpleCGI = runFastCGIConcurrent 10 . serverPartToCGI
main = simpleCGI handleRequest

handleRequest = return $ toResponse "Howdy From Happstack on FastCGI"

Help! Can you run Happstack as a CGI?
king, avatar, owl, ozten, austin
Does anyone already have code for running a Happstack app as a CGi instead of a HTTP Server?

Searching for a CGI adapter or backend to Happstack, I didn't find anything. The documentation mentions you can do it... but it isn't clear if it works out of the box.

I was able to find the happstack-fastcgi package. For fun, I tried converting my app to fast-cgi, following the blog post announcing the project. No dice.
I changed
main = handleSqlError $ trace "Starting up, try port 8080" (simpleHTTP (Conf 8080 Nothing) $ handleRequest)

main = simpleCGI handleRequest

simpleCGI :: (ToMessage a) => ServerPartT IO a -> IO ()
simpleCGI = runFastCGIConcurrent 10 . serverPartToCGI 

I compiled with
ghc --make -package cgi -package xhtml -o main.fcgi Main.hs

when I run it via apache I get
[Tue Sep 01 23:11:12 2009] [error] [client] FastCGI: incomplete headers (0 bytes) received from server "/home/some/web/main.fcgi"

I'd really like to find out how to run my app under plain old CGI, so that I can host it at NearlyFreeSpeech. They don't support FastCGI, nor long running processes like the Server mode.

Segmentation Fault and small files for errors
king, avatar, owl, ozten, austin
I don't know if I should be proud of myself or not... but my toy application has Seg Faulted ghc :/

I found to suspicious things
  • Calling commit on a connection that had already been disconnected

  • Trying read an int out of the textual representation of a
    and insert it into the database

I'm not quite sure, but fixing those two things have fixed the issue.

Another thing I'm noticing is to keep files extremely small, because while compile errors are verbose, runtime error reporting in ghci is very weak. Seg Fault gave me nothing... The error
Prelude.read: no parse

Gives me just a filename and no line number.

I'm excited I've reached a milestone in my toy application... I can

  • Send out HTML

  • Include data from the Database in the HTML

  • Process input from a form

  • Save the data to the db

  • Do a redirect

It's taken quite a few hours in 30 minute chunks to get this far. It's a good problem for exercising basic Haskell knowledge.

Being explicit helps compilation
king, avatar, owl, ozten, austin
It seems like I should be exact as possible with type signatures as I'm learning. For example I was using:
doWeight :: (ServerMonad m) => String -> m Response

which is all fine and good, until I change the String into a Maybe Stats. Then I ran into some compilation errors and I figured it was with my Maybe plumbing or maybe the IO of the database connection. My compilation error was
    Ambiguous constraint `ServerMonad m'
        At least one of the forall'd type variables mentioned by the constraint
        must be reachable from the type after the '=>'
    In the type signature for `doWeight':
      doWeight :: (ServerMonad m) => ServerPartT IO Response
Failed, modules loaded: Config, StatsDal, Stats, FiveBeeX, WeightView.

It seems like the biggest clue, which I often miss, is to pay attention to every part of the compilation error message.... what line and character? Ambiguous constraint... and then the hint of the actual type signature ServerPartT IO Response.

After fumbeling around, I remembred by looking at another one of my function type signatures that m Response was indeed ServerPartT IO Response, so without changing the implementation, but just the type signature to
doWeight :: Maybe Stats -> ServerPartT IO Response

everything compiles and works. I'm just so used to the issue being the implementation, maybe always being explicit with the Type signature will reduce these compilation errors and red herrings.

liftIO and a Formal Haskell Learning Curve
king, avatar, owl, ozten, austin
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
Read more...Collapse )

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
Read more...Collapse )

Where can I put my debug statements?
king, avatar, owl, ozten, austin
I'm not much on debuggers and rely on the REPL or println statements to learn what a piece of code is doing (or not doing). A frustration I've been having when learning Haskell, is not knowing where I could use Debug.Trace's trace function in my code. The module Debug.Trace provides two methods.
putTraceMsg :: String -> IO ()
trace :: String -> a -> a

I chose to go with putTaceMsg... because what the heck is that a -> a all about? Okay, so I plopped it into my code and voila, it compiles and I get to see my output. A day later I added it to a different chunk of code and it won't compile.

I was frustrated and confused. Then I noticed that it worked in an IO() context, but not in a pure function... Hmm.
Read MoreCollapse )
Example: To inject a bit of tracing, just wrap an expression in trace. Before and after, it retains the same shape:
  some f
  trace "hello world" (some f)

Related learning, while trying to figure this out: I've been avoiding declaring the Type signature of functions, until I had them "figured out". It sounds like I need to go the other way around, so that I'll be sure that the pile of function calls maintains the correct shape.

Haskwhal <- Eval Scheme, Apply Learnings
king, avatar, owl, ozten, austin
Introducing Haskwhal, Missteps of a Narwhal calf...

Hello again... I originally created this journal to track my progress through The Structure and Interpretation of Computer Programs. Until this post, it was named "Eval Scheme, Apply Learnings".

I'm moving on to study Haskell from the excellent book Real World Haskell. A new name is in order... so it's Haskwhal. To tidy up, I've re-tagged all the previous entries with Eval Scheme, Apply Learnings. As a Lifelong Learner I try to learn a new programming language every 18 months, to learn new concepts and warp my mind a bit more.

Going forward I'm looking forward to doing a better job of using the "Friends" features of livejournal to find other newbie Haskellers, asking questions here in the journal, document my failures and successes, and generally learn in the open.

case journalEntry of
  Just learned -> apply $ whatWas $ learned 
  Nothing -> getAClue $ readComments

Finished SICP last April
king, avatar, owl, ozten, austin
Shame on me... I have been super busy with my new gig. So I finished my independent study on SICP and got my grade back... A boo ya. I turned in a ton of work and it has been a very enlightening and worth while exercise. I really enjoyed working through SICP and STPL. I have not been doing any Lisp stuff since late-April. I will be focusing much more on Lisp in C's clothing aka JavaScript. I probably won't be updating this livejournal anymore ( and I wasn't very good at posting frequently during this study anywhoos ). Follow me at ozten.com

Gnuplot in Action
king, avatar, owl, ozten, austin
My friend and colleague Philipp K. Janert is writing a book on gnuplot. I am a technical reviewer and have thoroughly enjoyed the experience so far.

The title is Gnuplot in Action: Understanding Data with Graphs. It really coming along swimmingly! gnuplot is a really interesting graphing application. Much like ruby's irb, it gives you an interactive REPL ( read evaluate print loop ) where you can explore a dataset visually. There isn't a contemporary GUI, so figuring out how to setup and use the program has been a chore in the past, just working from man pages.

This book revels the cultural aspects of how to really use the program, or incorporate it into systems by setting up the environment and writing little reusable commands. Before I had seen gnuplot, I thought you would have to fire up a spreadsheet program or Mathematica to do graphs. In reality, you can be trying to troubleshoot an issue by analyzing the frequency of errors in a server log, and then pipe the results into a file and display it with Gnuplot to spot trends and see relationships.

Another nice aspect of the book is the background information on logarithms and logarithmic plots, a review of color spaces, and some details around how to expose quantitative information in your graphs. It also touches on how to integrate your graphs into LaTeX.

I was surprised at how many backends gnuplot comes with. I installed it on Mac OS X Tiger and was able to generate SVG, png, and Cocoa output. I had recently added gnuplot to my toolbag, so the chance to review this book couldn't have come at a better time.

Check the sample chapter Essential gnuplot.

You are viewing ozten