1

I am following this post about the reader monad in Haskell.

It starts with the definition:

load :: Config -> String -> IO String
load config x -> readFile (config ++ x)

Where Config is a type alias for String and it represents a directory name.

The method is meant to display on screen the content of a file, for example "./myFile.txt".

I run this method from ghci with:

load "./" "myFile.txt"

The second example introduces the reader monad:

load :: (MonadReader Config m, MonadIO m) => String -> m String
load x = do
    config <- ask
    liftIO $ readFile (config ++ x)

Question is: how do I run it from ghci?

I have tried with things like:

(runReader load "myFile.txt") "./"

but no joy.

What is the command that loads ./myFile.txt?

Marco Faustinelli
  • 3,734
  • 5
  • 30
  • 49

1 Answers1

3
runReaderT (load "myFile.txt") "./" :: IO String
Daniel Wagner
  • 145,880
  • 9
  • 220
  • 380
  • You are a prince. Thank you! Can you further expand WHY do I need to run a transformer? I suppose that there is some monad layering hidden in the type m, but I cannot see it, yet. – Marco Faustinelli Sep 12 '19 at 05:31
  • 1
    @MarcoFaustinelli To a first approximation, the `MonadReader Config m` constraint says that `m` is a monad transformer stack which contains `ReaderT Config` somewhere in the stack. The `MonadIO m` constraint says that the monad at the bottom of the stack is `IO`. So `ReaderT Config IO` is, in some sense, a sort of "minimal" monad transformer stack that satisfies the constraint. – Daniel Wagner Sep 12 '19 at 06:09
  • I am not familiar with naming transformers [without the T at the end](https://github.com/Muzietto/transformerz); but if I look at [hackage](http://hackage.haskell.org/package/mtl-2.2.2/docs/Control-Monad-Reader.html#g:1) I do not see any instance of MonadReader that will fit the usage here. What am I missing? – Marco Faustinelli Sep 12 '19 at 06:33
  • 2
    @MarcoFaustinelli `instance Monad m => MonadReader r (ReaderT r m)`, fourth from the bottom of the list of instances at the second link you provided, is the one being used here. – Daniel Wagner Sep 12 '19 at 06:36