Search code examples
haskellmonadsparse-error

Parse error in a `do` block on input `<-`


In my textbook, there is an example of how to take out the first and third character from a string using parsers. I have tried to write it down as it stands in the book.

type Parser a = String -> [(a,String)]

item = \inp -> case inp of
    []-> []
    (x:xs) -> [(x,xs)]

p = do 
    x <- item
    item 
    y <- item
    return (x,y)

However I get the message:

dataTest.hs:47:11:
parse error on input ‘<-’
Perhaps this statement should be within a 'do' block?

As I was not able to figure out what went wrong, I wrote down this for a less abstract version of the code:

q = item >>= \x1 -> 
    item >>= \x2 ->
    item >>= \x3 -> 
    return (x1, x3)

But as shown below:

*Main> q "abc"
([('a',"bc")],[('a',"bc")],[('a',"bc")])

I get the wrong output.

So I have two questions:

  1. How should I write p?
  2. How should I write q?

Solution

  • It's just a formatting thing. Start a newline:

    p = do
        x <- item
        item
        y <- item
        return (x,y)
    

    As for q, remember that do {x <- item; f x} is equivalent to item >>= \x -> f x, and the second one is redundant, so:

    q = do
        x1 <- item 
        item
        x3 <- item
        return (x1, x3)
    

    ...which is equivalent to p.