mcNogard
mcNogard

Reputation: 49

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?

Upvotes: 2

Views: 5868

Answers (1)

AJF
AJF

Reputation: 11913

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.

Upvotes: 3

Related Questions