rogergl
rogergl

Reputation: 3771

How to use Monad.Writer for tracing?

My code looks like this:

I would like to use tell inside the tokenize function in order to write to the same Writer Monad. Is this possible ?

tokenize :: T.Text -> T.Text -> [Token]
tokenize t token
   | T.null t = addToken token []
   | h == ' ' = addToken token (tokenize r "")
   | h == '"' = let (t', r') = consumeString r
                in addToken t' (tokenize r' "")
   | otherwise = tokenize r (T.snoc token h)
   where h = T.head t
         r = T.tail t

parse :: [T.Text] -> W.Writer String [Token]
parse lines = do
    let x = concatMap (\l -> tokenize l "") lines
    W.tell "hello"
    return x

main :: IO ()
main = do
    content <- readContent
    let lines = toTextList content
    let (res, log) = W.runWriter $ parse lines
    forM_ res $ \x ->
        print x
    print log

Upvotes: 0

Views: 212

Answers (1)

user2297560
user2297560

Reputation: 2983

You just need to lift the result of tokenize into the Writer:

tokenize :: T.Text -> T.Text -> W.Writer [Token]
tokenize t token
   | T.null t = return $ addToken token []
   | h == ' ' = return $ addToken token (tokenize r "")
   | h == '"' = let (t', r') = consumeString r
                in return $ addToken t' (tokenize r' "")
   | otherwise = return $ tokenize r (T.snoc token h)
   where h = T.head t
         r = T.tail t

Then parse has to change to handle a monadic result from tokenize:

parse :: [T.Text] -> W.Writer String [Token]
parse lines = do
    x <- concat <$> mapM (\l -> tokenize l "") lines
    W.tell "hello"
    return x

Upvotes: 1

Related Questions