Search code examples
haskellparsec

Convert function into 1 liner


After doing

>import Text.ParserCombinators.Parsec

and

>data Tag = MkTag String deriving Show 

I have this function

parseDiv = do 
  string "<div>" 
  return (MkTag "div")

and I want to convert it into a 1 liner for ghci. I could have used :{ ... :} but want to understand why it didn't work. This is the 1 line

>let parseDiv  = do { string "<div>";return $ MkTag "div" }


<interactive>:7:5: error:
* Non type-variable argument
    in the constraint: Text.Parsec.Prim.Stream s m Char
  (Use FlexibleContexts to permit this)
* When checking the inferred type
    parseDiv :: forall s (m :: * -> *) u.
                Text.Parsec.Prim.Stream s m Char =>
                Text.Parsec.Prim.ParsecT s u m Tag

It works if I define it across multiple lines.


Solution

  • You can define this with (<$) :: Functor f => a -> f b -> f a. This thus performs a functor mapping with x <$ u = fmap (const x) u:

    {-# LANGUAGE FlexibleContexts #-}
    
    parseDiv :: Stream s m Char => ParsecT s u m Tag
    parseDiv = MkTag "div" <$ string "<div>"