1

I have the following Parser

newtype Parser a = P (String -> [(a,String)])

and I need to implement the bind on its implementation as a Monad. I have that the return is defined as

instance Monad Parser where
    return v = P (\inp -> [(v,inp)])

To implement p >>= f I know this much: p is a Parser object and f has type declaration

f :: a -> Parser b

So I'm thinking the value of p >>= f needs to be a Parser object which wraps a function. That function's argument is a String. So I'm guessing the function should "open up p", get its function, apply that to the input string, get an object of type [(a, String)], then ... I guess maybe apply f to every first coordinate in each tuple, then use the resulting Parser's function and apply it to the second coordinate ... and make a list of all of those tuples?

At this point I get pretty foggy on whether I got this right and if so, how to do it. Maybe I should write a helper function with type

trans :: [(a,String)] -> (a -> Parser b) -> [(b,String)]

But before getting into that, I wanted to check if my confused description of what I should be doing rings true.

4
  • Hint: what is a bind for list? Commented Dec 9, 2018 at 0:34
  • @WillemVanOnsem fmap. Is the hint that trans should make use of fmap? Or should is it suggesting that I not create this trans function at all and fmap does everything for me? Commented Dec 9, 2018 at 0:38
  • 1
    Your informal description looks right to me. Try to turn that into code. Commented Dec 9, 2018 at 0:39
  • 1
    @Addem: no, the bind of a list is concatMap, and it is quite similar here. Commented Dec 9, 2018 at 0:40

1 Answer 1

1
instance Monad Parser where
    return v = P (\inp -> [(v,inp)])
    P p >>= f = P (\inp -> do
        (x,u) <- p inp
        let P q = f x
        q u
        )
Sign up to request clarification or add additional context in comments.

5 Comments

p inp has type [(a,String)], right? Is the do-notation just grabbing the first element of the list if it exists? Does this mean everything else gets thrown away, if it exists?
@Addem do-notation is a syntactic sugar for any monadic action. Here, it is for a list monad. As a consequence, (x,u) represents every element of p inp.
Oh, this is due to the fact that bind for list is concatMap which iterates over the elements of the list?
@Addem Yes, exactly.
@Addem In the list monad, do is essentially another syntax for list comprehensions: ... = P (\inp -> [r | (x,u) <- p inp , let P q = f x , r <- q u]) is equivalent.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.