I’m stupid in haskell too!

My goal was to diagnose a build time failure bootstrapping ghcjs (specifically, a mysterious and unexplained

/bin/sh: 1: cannot open ../../data/primops-js.txt: No such file

Just by seeing what directory I was in.

I started at:

main :: IO ()
main = do let hooks = simpleUserHooks {
regHook = addPrimModule
$ regHook simpleUserHooks,
instHook = myInstHook,
buildHook = build_primitive_sources
$ buildHook simpleUserHooks,
haddockHook = addPrimModuleForHaddock
$ build_primitive_sources
$ haddockHook simpleUserHooks }
putStrLn getCurrentDirectory
defaultMainWithHooks hooks

And got the quite poetic:

boot/ghc-prim/dist/setup/setup.hs:34:20:
Couldn’t match type ‘IO FilePath’ with ‘[Char]’
Expected type: String
Actual type: IO FilePath
In the first argument of ‘putStrLn’, namely ‘getCurrentDirectory’
In a stmt of a ‘do’ block: putStrLn getCurrentDirectory

I read:

And despite that it was mostly unhelpful, the comment:

We’ve now moved on to failings of Haskell’s learning curve. A hint: there is a function with type a -> IO a, but it's disguised as (Monad m) => a -> m a

Finally clicked. A bind operation on the monad pulls a value out of the effect progression and makes it visible in the rest of the expressions. What I really wanted was:

main :: IO ()
main = do let hooks = simpleUserHooks {
regHook = addPrimModule
$ regHook simpleUserHooks,
instHook = myInstHook,
buildHook = build_primitive_sources
$ buildHook simpleUserHooks,
haddockHook = addPrimModuleForHaddock
$ build_primitive_sources
$ haddockHook simpleUserHooks }
curdir <- getCurrentDirectory
putStrLn curdir
defaultMainWithHooks hooks

I’m definitely slightly less stupid than the 7,456,050,932nd smartest person (who will be a baby until at least 2018, and therefore almost certainly not great at haskell yet).

One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.