need to convert monard chainrl to applicative style - parsing

Hi have parser using monard
chainr1 p op = scan
where scan = p >>= rest
rest x = do f <- op
y <- scan
return (f x y)
+++ return

Given this:
do
f <- op
y <- scan
return (f x y)
You could desugar do notation and then use rewriting rules to arrive at an applicative version, but the simpler method is to recognise the pattern of parsing op then scan and combining them somehow with a function:
do
a <- …
b <- …
return (… a … b …)
For this pattern you can use liftA2 or … <$> … <*> …:
liftA2 (\ f y -> f x y) op scan
(\ f y -> f x y) <$> op <*> scan
You can then eta-reduce y:
(\ f -> f x) <$> op <*> scan
And then make it point-free using an operator section with ($):
($ x) <$> op <*> scan
($ x) or flip ($) x is a function that takes a function and applies it to x, e.g. map ($ 2) [(* 3), (+ 5)] == [6, 7].

Put {-# LANGUAGE ApplicativeDo #-} at the top of your file, and your do block will then be desugared to use Applicative instead of Monad. Also, you should change your return to pure.

Related

how to print intermediate result in Functor and Applicative in Haskell

I am reading the book Programming in Haskell 2nd by Graham Hutton.
https://www.cs.nott.ac.uk/~pszgmh/pih.html#slides
When it comes to chapter 13.4 Sequencing parsers, it contains the following functions:
> parse three "abcdef"
[((’a’,’c’),"def")]
> parse three "ab"
[]
I would like to understand what are the intermediate steps to evaluate them behind the scene. You can find the working source code for the Functor and Applicative for the Parser here:
import Control.Applicative
import Data.Char
-- Basic definitions
newtype Parser a =
P (String -> [(a, String)])
parse (P p) inp = p inp
item :: Parser Char
item = P (\inp -> case inp of
[] -> []
(x:xs) -> [(x, xs)])
-- Sequencing parsers
instance Functor Parser
-- fmap :: (a -> b) -> Parser a -> Parser b
where
fmap g p =
P
(\inp ->
case parse p inp of
[] -> []
[(v, out)] -> [(g v, out)])
--parse (fmap toUpper item) "abc"
instance Applicative Parser
-- pure :: a -> Parser a
where
pure v = P (\inp -> [(v, inp)])
-- <*> :: Parser (a -> b) -> Parser a -> Parser b
pg <*> px =
P
(\inp ->
case parse pg inp of
[] -> []
[(g, out)] -> parse (fmap g px) out)
three :: Parser (Char, Char)
three = pure g <*> item <*> item <*> item
where
g x y z = (x, z)
I have attempted it by substituting the definitions from Functor and Applicative in the following way, but dont know how to do it further:
parse three "abc"
three :: Parser (Char,Char)
three
= pure g <*> item <*> item <*> item
=P (\inp -> [(g,inp)]) <*> item <*> item <*> item (apply pure v)
-----------------------------------------------------------------------------------------------------------
=P (
\inp -> case parse P (\inp -> [(g,inp)]) inp of (apply pg <*> px)
[] -> []
[(g,out)] -> parse (fmap g item) out
)
<*> item <*> item
-----------------------------------------------------------------------------------------------------------
=P (
\inp -> case (\inp -> [(g,inp)]) inp of (apply parse (P p) inp = p inp
[] -> []
[(g,out)] -> parse (fmap g item) out
)
<*> item <*> item
-----------------------------------------------------------------------------------------------------------
Here, inp=”abc”, (\inp -> [(g,inp)]), inp = [ (f x y z =(x,z), “abc” )]
=P (
parse (
fmap g item
) out
) (apply \inp -> [(g,inp)] on inp)
<*> item <*> item
(This is in response to the 'Based on the suggestion of #Daniel Wagner, I expand on fmap g p:' update)
Is the last substitution correct?
It's impossible to answer because steps before that are incorrect.
There are several problems with your expansion, indicating that you're being sloppy when writing, which has led to mistakes. There might also be conceptual problems.
For example, when you inline three = P ... into parse three "abc", you didn't put parentheses around P ..., leading to this line:
parse P (parse (P ...)) <*> item <*> item "abc"
This is most likely syntactically incorrect, as it would be parsed like
(parse P (parse (P ...))) <*> item <*> (item "abc")
While you likely meant:
parse ((P ...) <*> item <*> item) "abc"
If you think, well I'm just doing this to make things easier to write, then check this out: This syntax error also led you to erroneously work on the parse P (parse (P ...)) part independently of <*> item <*> item "abc", which a serious mistake and made most of everything following that irrelevant.
Another thing is this:
Here, inp="abc", (\inp -> [(g,inp)]), inp = [ (f x y z =(x,z), "abc" )]
This line makes no sense at all. Since you are just expanding three, It's not valid to say that inp is anything. Consider (\x -> x). The x here is merely to establish the relationship that the result is the same as the argument, and is not any particular value. This is what is meant by it being a bound variable.
(And I don't even know what you're talking about when you say (\inp -> [(g,inp)]), inp = [ (f x y z =(x,z), "abc" )]. Maybe you can clarify?)
This also means that the following makes no sense
(\inp -> case parse item inp of [] -> []; [(v, out)] -> [(g v, out)]))<*> item <*> item “abc”
={substitute inp for "abc"}
case parse item "abc" of [] -> []; [(v, out)] -> [(g v, out)]<*> item <*> item
There are multiple problems here. To begin with, the first line has an extra close paren, which makes it hard to see what you mean. If we ignore that, then before you had (\inp ->) <*> item ..., but afterwards you did not put parens around the case expression, making <*>.
Also, it seems that you want to do a beta-reduction here. A beta reduction always has the form (\v -> E) a, in which the lambda is directly applied to an argument. You cannot just say randomly that 'v is equal to a' and jump around in expressions.
For example, If we have f (\x -> x + 1) 3, is it right to reduce that to f 4? No, because the lambda isn't being applied to 3.
This means that even if the first half is right, the second half of what you wrote is based on a nonsensical step and is irrelevant.
I would very much want to tell you how to fix your reduction, but I'm sorry to say that I think what you wrote is beyond repair by now. If you want to have a correct reduction trace, please be more careful with both the syntax and the validity of each step, and do everything again from scratch.
As an aid, there are several things you should check to see if things went wrong:
Each step should be syntactically valid. No unbound variables, no missing parens, etc.
If the original expression typechecks, then each step must also typecheck and have the same type.
It's a good start. Your last step doesn't look quite right. Stripping off the shared parts, you've written that
\inp -> case (\inp -> [(g,inp)]) inp of [] -> []; [(g, out)] -> parse (fmap g item) out
=
parse (fmap g item) out
This equation doesn't look quite right to me: the former is a function, and the latter isn't. Additionally, the latter refers to the free variable out, while the former doesn't (because out is bound by the pattern match it's enclosed in). A more careful continuation looks like this:
\inp -> case (\inp -> [(g,inp)]) inp of [] -> []; [(g, out)] -> parse (fmap g item) out
= { beta reduction, substituting inp for inp }
\inp -> case [(g, inp)] of [] -> []; [(g, out)] -> parse (fmap g item) out
= { case reduction, substituting g for g and inp for out }
\inp -> parse (fmap g item) inp
If you like, you could then eta-reduce this to parse (fmap g item). Plugging this back into the shared parts we dropped above, we have:
three
=
P (parse (fmap g item)) <*> item <*> item
The result can be verified in ghci:
*Parsing> parse three "abc"
[(('a','c'),"")]
*Parsing> let g x y z = (x,z)
*Parsing> parse (P (parse (fmap g item)) <*> item <*> item) "abc"
[(('a','c'),"")]
As next steps, there are three places you could do your next definition-expansion to enable further progress:
You could expand the fmap in fmap g item.
You could expand the inner (<*>) in P (...) <*> item.
You could expand the outer (<*>) in (P (...) <*> item) <*> item.
Good luck!

applicative functor: <*> and partial application, how it works

I am reading the book Programming in Haskell by Graham Hutton and I have some problem to understand how <*> and partial application can be used to parse a string.
I know that pure (+1) <*> Just 2
produces Just 3
because pure (+1) produces Just (+1) and then Just (+1) <*> Just 2
produces Just (2+1) and then Just 3
But in more complex case like this:
-- Define a new type containing a parser function
newtype Parser a = P (String -> [(a,String)])
-- This function apply the parser p on inp
parse :: Parser a -> String -> [(a,String)]
parse (P p) inp = p inp
-- A parser which return a tuple with the first char and the remaining string
item :: Parser Char
item = P (\inp -> case inp of
[] -> []
(x:xs) -> [(x,xs)])
-- A parser is a functor
instance Functor Parser where
fmap g p = P (\inp -> case parse p inp of
[] -> []
[(v, out)] -> [(g v, out)])
-- A parser is also an applicative functor
instance Applicative Parser where
pure v = P (\inp -> [(v, inp)])
pg <*> px = P (\inp -> case parse pg inp of
[] -> []
[(g, out)] -> parse (fmap g px) out)
So, when I do:
parse (pure (\x y -> (x,y)) <*> item <*> item) "abc"
The answer is:
[(('a','b'),"c")]
But I don't understand what exactly happens.
First:
pure (\x y -> (x,y)) => P (\inp1 -> [(\x y -> (x,y), inp1)])
I have now a parser with one parameter.
Then:
P (\inp1 -> [(\x y -> (x,y), inp1)]) <*> item
=> P (\inp2 -> case parse (\inp1 -> [(\x y -> (x,y), inp1)]) inp2 of ???
I really don't understand what happens here.
Can someone explain, step by step, what's happens now until the end please.
Let's evaluate pure (\x y -> (x,y)) <*> item. The second application of <*> will be easy once we've seen the first:
P (\inp1 -> [(\x y -> (x,y), inp1)]) <*> item
We replace the <*> expression with its definition, substituting the expression's operands for the definition's parameters.
P (\inp2 -> case parse P (\inp1 -> [(\x y -> (x,y), inp1)]) inp2 of
[] -> []
[(g, out)] -> parse (fmap g item) out)
Then we do the same for the fmap expression.
P (\inp2 -> case parse P (\inp1 -> [(\x y -> (x,y), inp1)]) inp2 of
[] -> []
[(g, out)] -> parse P (\inp -> case parse item inp of
[] -> []
[(v, out)] -> [(g v, out)]) out)
Now we can reduce the first two parse expressions (we'll leave parse item out for later since it's basically primitive).
P (\inp2 -> case [(\x y -> (x,y), inp2)] of
[] -> []
[(g, out)] -> case parse item out of
[] -> []
[(v, out)] -> [(g v, out)])
So much for pure (\x y -> (x,y)) <*> item. Since you created the first parser by lifting a binary function of type a -> b -> (a, b), the single application to a parser of type Parser Char represents a parser of type Parser (b -> (Char, b)).
We can run this parser through the parse function with input "abc". Since the parser has type Parser (b -> (Char, b)), this should reduce to a value of type [(b -> (Char, b), String)]. Let's evaluate that expression now.
parse P (\inp2 -> case [(\x y -> (x,y), inp2)] of
[] -> []
[(g, out)] -> case parse item out of
[] -> []
[(v, out)] -> [(g v, out)]) "abc"
By the definition of parse this reduces to
case [(\x y -> (x,y), "abc")] of
[] -> []
[(g, out)] -> case parse item out of
[] -> []
[(v, out)] -> [(g v, out)]
Clearly, the patterns don't match in the first case, but they do in the second case. We substitute the matches for the patterns in the second expression.
case parse item "abc" of
[] -> []
[(v, out)] -> [((\x y -> (x,y)) v, out)]
Now we finally evaluate that last parse expression. parse item "abc" clearly reduces to [('a', "bc")] from the definition of item.
case [('a', "bc")] of
[] -> []
[(v, out)] -> [((\x y -> (x,y)) v, out)]
Again, the second pattern matches and we do substitution
[((\x y -> (x,y)) 'a', "bc")]
which reduces to
[(\y -> ('a', y), "bc")] :: [(b -> (Char, b), String)] -- the expected type
If you apply this same process to evaluate a second <*> application, and put the result in the parse (result) "abc" expression, you'll see that the expression indeed reduces to[(('a','b'),"c")].
What helped me a lot while learning these things was to focus on the types of the values and functions involved. It's all about applying a function to a value (or in your case applying a function to two values).
($) :: (a -> b) -> a -> b
fmap :: Functor f => (a -> b) -> f a -> f b
(<*>) :: Applicative f => f (a -> b) -> f a -> f b
So with a Functor we apply a function on a value inside a "container/context" (i.e. Maybe, List, . .), and with an Applicative the function we want to apply is itself inside a "container/context".
The function you want to apply is (,), and the values you want to apply the function to are inside a container/context (in your case Parser a).
Using pure we lift the function (,) into the same "context/container" our values are in (note, that we can use pure to lift the function into any Applicative (Maybe, List, Parser, . . ):
(,) :: a -> b -> (a, b)
pure (,) :: Parser (a -> b -> (a, b))
Using <*> we can apply the function (,) that is now inside the Parser context to a value that is also inside the Parser context. One difference to the example you provided with +1 is that (,) has two arguments. Therefore we have to use <*> twice:
(<*>) :: Applicative f => f (a -> b) -> f a -> f b
x :: Parser Int
y :: Parser Char
let p1 = pure (,) <*> x :: Parser (b -> (Int, b))
let v1 = (,) 1 :: b -> (Int, b)
let p2 = p1 <*> y :: Parser (Int, Char)
let v2 = v1 'a' :: (Int, Char)
We have now created a new parser (p2) that we can use just like any other parser!
. . and then there is more!
Have a look at this convenience function:
(<$>) :: Functor f => (a -> b) -> f a -> f b
<$> is just fmap but you can use it to write the combinators more beautifully:
data User = User {name :: String, year :: Int}
nameParser :: Parser String
yearParser :: Parser Int
let userParser = User <$> nameParser <*> yearParser -- :: Parser User
Ok, this answer got longer than I expected! Well, I hope it helps. Maybe also have a look at Typeclassopedia which I found invaluable while learning Haskell which is an endless beautiful process . . :)
TL;DR: When you said you "[now] have a parser with one parameter" inp1, you got confused: inp1 is an input string to a parser, but the function (\x y -> (x,y)) - which is just (,) - is being applied to the output value(s), produced by parsing the input string. The sequence of values produced by your interim parsers is:
-- by (pure (,)):
(,) -- a function expecting two arguments
-- by the first <*> combination with (item):
(,) x -- a partially applied (,) function expecting one more argument
-- by the final <*> combination with another (item):
((,) x) y == (x,y) -- the final result, a pair of `Char`s taken off the
-- input string, first (`x`) by an `item`,
-- and the second (`y`) by another `item` parser
Working by equational reasoning can oftentimes be easier:
-- pseudocode definition of `fmap`:
parse (fmap g p) inp = case (parse p inp) of -- g :: a -> b , p :: Parser a
[] -> [] -- fmap g p :: Parser b
[(v, out)] -> [(g v, out)] -- v :: a , g v :: b
(apparently this assumes any parser can only produce 0 or 1 results, as the case of a longer list isn't handled at all -- which is usually frowned upon, and with good reason);
-- pseudocode definition of `pure`:
parse (pure v) inp = [(v, inp)] -- v :: a , pure v :: Parser a
(parsing with pure v produces the v without consuming the input);
-- pseudocode definition of `item`:
parse (item) inp = case inp of -- inp :: ['Char']
[] -> []
(x:xs) -> [(x,xs)] -- item :: Parser 'Char'
(parsing with item means taking one Char off the head of the input String, if possible); and,
-- pseudocode definition of `(<*>)`:
parse (pg <*> px) inp = case (parse pg inp) of -- px :: Parser a
[] -> []
[(g, out)] -> parse (fmap g px) out -- g :: a -> b
(<*> combines two parsers with types of results that fit, producing a new, combined parser which uses the first parse to parse the input, then uses the second parser to parse the leftover string, combining the two results to produce the result of the new, combined parser);
Now, <*> associates to the left, so what you ask about is
parse ( pure (\x y -> (x,y)) <*> item <*> item ) "abc"
= parse ( (pure (,) <*> item1) <*> item2 ) "abc" -- item_i = item
the rightmost <*> is the topmost, so we expand it first, leaving the nested expression as is for now,
= case (parse (pure (,) <*> item1) "abc") of -- by definition of <*>
[] -> []
[(g2, out2)] -> parse (fmap g2 item2) out2
= case (parse item out2) of -- by definition of fmap
[] -> []
[(v, out)] -> [(g2 v, out)]
= case out2 of -- by definition of item
[] -> []
(y:ys) -> [(g2 y, ys)]
Similarly, the nested expression is simplified as
parse (pure (,) <*> item1) "abc"
= case (parse (pure (\x y -> (x,y))) "abc") of -- by definition of <*>
[] -> []
[(g1, out1)] -> parse (fmap g1 item1) out1
= case (parse item out1) of ....
= case out1 of
[] -> []
(x:xs) -> [(g1 x, xs)]
= case [((,), "abc")] of -- by definition of pure
[(g1, out1)] -> case out1 of
[] -> []
(x:xs) -> [(g1 x, xs)]
= let { out1 = "abc"
; g1 = (,)
; (x:xs) = out1
}
in [(g1 x, xs)]
= [( (,) 'a', "bc")]
and thus we get
= case [( (,) 'a', "bc")] of
[(g2, out2)] -> case out2 of
[] -> []
(y:ys) -> [(g2 y, ys)]
I think you can see now why the result will be [( ((,) 'a') 'b', "c")].
First, I want to emphasize one thing. I found that the crux of understanding lies in noticing the separation between the Parser itself and running the parser with parse.
In running the parser you give the Parser and input string to parse and it will give you the list of possible parses. I think that's probably easy to understand.
You will pass parse a Parser, which may be built using glue, <*>. Try to understand that when you pass parse the Parser, a, or the Parser, f <*> a <*> b, you will be passing it the same type of thing, i.e. something equivalent to (String -> [(a,String)]). I think this is probably easy to understand as well, but still it takes a while to "click".
That said, I'll talk a little about the nature of this applicative glue, <*>. An applicative, F a is a computation that yields data of type a. You can think of a term such as
... f <*> g <*> h
as a series of computations which return some data, say a then b then c. In the context of Parser, the computation involve f looking for a in the current string, then passing the remainder of the string to g, etc. If any of the computations/parses fails, then so does the whole term.
Its interesting to note that any applicative can be written with a pure function at the beginning to collect all those emitted values, so we can generally write,
pure3ArgFunction <$> f <*> g <*> h
I personally find the mental model of emitting and collecting helpful.
So, with that long preamble over, onto the actual explanation. What does
parse (pure (\x y -> (x,y)) <*> item <*> item) "abc"
do? Well, parse (p::Parser (Char,Char) "abc" applies the parser, (which I renamed p) to "abc", yielding [(('a','b'),"c")]. This is a successful parse with the return value of ('a','b') and the leftover string, "c".
Ok, that's not the question though. Why does the parser work this way? Starting with:
.. <*> item <*> item
item takes the next character from the string, yields it as a result and passes the unconsumed input. The next item does the same. The beginning can be rewritten as:
fmap (\x y -> (x,y)) $ item <*> item
or
(\x y -> (x,y)) <$> item <*> item
which is my way of showing that the pure function does not do anything to the input string, it just collects the results. When looked at in this light I think the parser should be easy to understand. Very easy. Too easy. I mean that in all seriousness. Its not that the concept is so hard, but our normal frame of looking at programming is just too foreign for it to make much sense at first.
Some people below did great jobs on "step-by-step" guides for you to easily understand the progress of computation to create the final result. So I don't replicate it here.
What I think is that, you really need to deeply understand about Functor and Applicative Functor. Once you understand these topics, the others will be easy as one two three (I means most of them ^^).
So: what is Functor, Applicative Functor and their applications in your problem?
Best tutorials on these:
Chapter 11 of "Learn You a Haskell for a great good": http://learnyouahaskell.com/functors-applicative-functors-and-monoids.
More visual "Functors, Applicatives, And Monads in Pictures": http://adit.io/posts/2013-04-17-functors,_applicatives,_and_monads_in_pictures.html.
First, when you think about Functor, Applicative Functor, think about "values in contexts": the values are important, and the computational contexts are important too. You have to deal with both of them.
The definitions of the types:
-- Define a new type containing a parser function
newtype Parser a = P (String -> [(a,String)])
-- This function apply the parser p on inp
parse :: Parser a -> String -> [(a,String)]
parse (P p) inp = p inp
The value here is the value of type a, the first element of the tuple in the list.
The context here is the function, or the eventual value. You have to supply an input to get the final value.
Parser is a function wrapped in a P data constructor. So if you got a value b :: Parser Char, and you want to apply it to some input, you have to unwrap the inner function in b. That's why we have the function parse, it unwraps the inner function and applies it to the input value.
And, if you want to create Parser value, you have to use P data constructor wraps around a function.
Second, Functor: something that can be "mapped" over, specified by the function fmap:
fmap :: (a -> b) -> f a -> f b
I often call the function g :: (a -> b) is a normal function because as you see no context wraps around it. So, to be able to apply g to f a, we have to extract the a from f a somehow, so that g can be apply to a alone. That "somehow" depends on the specific Functor and is the context you are working in:
instance Functor Parser where
fmap g p = P (\inp -> case parse p inp of
[] -> []
[(v, out)] -> [(g v, out)])
g is the function of type (a -> b), p is of type f a.
To unwrap p, to get the value of of context, we have to pass some input value in: parse p inp, then the value is the 1st element of the tuple. Apply g to that value, get a value of type b.
The result of fmap is of type f b, so we have to wrap all the result in the same context, that why we have: fmap g p = P (\inp -> ...).
At this time, you might be wonder you could have an implementation of fmap in which the result, instead of [(g v, out)], is [(g v, inp)]. And the answer is Yes. You can implement fmap in any way you like, but the important thing is to be an appropriate Functor, the implementation must obey Functor laws. The laws are they way we deriving the implementation of those functions (http://mvanier.livejournal.com/4586.html). The implementation must satisfy at least 2 Functor laws:
fmap id = id.
fmap (f . g) = fmap f . fmap g.
fmap is often written as infix operator: <$>. When you see this, look at the 2nd operand to determine which Functor you are working with.
Third, Applicative Functor: you apply a wrapped function to a wrapped value to get another wrapped value:
<*> :: f (a -> b) -> f a -> f b
Unwrap the inner function.
Unwrap 1st value.
Apply the function and wrap the result.
In your case:
instance Applicative Parser where
pure v = P (\inp -> [(v, inp)])
pg <*> px = P (\inp -> case parse pg inp of
[] -> []
[(g, out)] -> parse (fmap g px) out)
pg is of type f (a -> b), px is of type f a.
Unwrap g from pg by parse pg inp, g is the 1st of the tuple.
Unwrap px and apply g to the value by using fmap g px. Attention, the result function only applies to out, in some case that is "bc" not "abc".
Wrap the whole result: P (\inp -> ...).
Like Functor, an implementation of Applicative Functor must obey Applicative Functor laws (in the tutorials above).
Fourth, apply to your problem:
parse (pure (\x y -> (x,y)) <*> item <*> item) "abc"
| f1 | |f2| |f3|
Unwrap f1 <*> f2 by passing "abc" to it:
Unwrap f1 by passing "abc" to it, we get [(g, "abc")].
Then fmap g on f2 and passing out="abc" to it:
Unwrap f2 get [('a', "bc")].
Apply g on 'a' get a result: [(\y -> ('a', y), "bc")].
Then fmap 1st element of the result on f3 and passing out="bc" to it:
Unwrap f3 get [('b', "c")].
Apply the function on 'b' get final result: [(('a', 'b'), "c")].
In conclusion:
Take some time for the ideas to "dive" into you. Especially, the laws derives the implementations.
Next time, design your data structure to easier understand.
Haskell is one of my favorite languages and I thing it will be yours soon, so be patient, it needs a learning curve and then you go!
Happy Haskell hacking!
Hmm I am not experienced with Haskell but my attempt on generating Functor and Applicative instances of the Parser type would be as follows;
-- Define a new type containing a parser function
newtype Parser a = P (String -> [(a,String)])
-- This function apply the parser p on inp
parse :: Parser a -> String -> [(a,String)]
parse (P p) inp = p inp
-- A parser which return a tuple with the first char and the remaining string
item :: Parser Char
item = P (\inp -> case inp of
[] -> []
(x:xs) -> [(x,xs)])
-- A parser is a functor
instance Functor Parser where
fmap g (P f) = P (\str -> map (\(x,y) -> (g x, y)) $ f str)
-- A parser is also an applicative functor
instance Applicative Parser where
pure v = P (\str -> [(v, str)])
(P g) <*> (P f) = P (\str -> [(g' v, s) | (g',s) <- g str, (v,_) <- f str])
(P g) <*> (P f) = P (\str -> f str >>= \(v,s1) -> g s1 >>= \(g',s2) -> [(g' v,s2)])
(10x very much for the helping of #Will Ness on <*>)
Accordingly...
*Main> parse (P (\s -> [((+3), s)]) <*> pure 2) "test"
[(5,"test")]
*Main> parse (P (\s -> [((,), s ++ " altered")]) <*> pure 2 <*> pure 4) "test"
[((2,4),"test altered")]

Haskell: How do you figure out the definition of <*> from a Monad definition?

I have a parser object defined:
newtype Parser a = Parser (String -> [(String, a)])
And a function to produce them:
produce :: a -> Parser a
produce x = Parser (\ts -> [(ts, x)])
And an instance of Monad for this parser object to allow me to bind multiple parsers into one:
instance Monad Parser where
return = produce
Parser px >>= f = Parser (\ts ->
concat([parse (f x) ts' | (ts', x) <- px ts]))
I have also been using <*> quite happily to chain multiple parsers for different types to parse a string with different parts within it.
Of course <*> is defined via the following:
(<*>) = ap
But I want to define it explicitly so that I am able to understand and explain how it works exactly and I have been unable to figure it out.
So how can I figure out how to explicitlly find the definition of ap or <*> in this instance?
Any advice on what <*> would be or how I should work it out is appreciated.
Thanks.
You can start from
f <*> x = do
f' <- f
x' <- x
return (f' x')
or, equivalently
f <*> x =
f >>= (\f' ->
x >>= (\x' ->
return (f' x')))
and then expand >>= and return as needed.

Writing Parser for Positive JSON Number w/ Decimal

Given the following definitions from Prof. Yorgey's UPenn class:
newtype Parser a = Parser { runParser :: String -> Maybe (a, String) }
satisfy :: (Char -> Bool) -> Parser Char
satisfy p = Parser f
where
f [] = Nothing -- fail on the empty input
f (x:xs) -- check if x satisfies the predicate
-- if so, return x along with the remainder
-- of the input (that is, xs)
| p x = Just (x, xs)
| otherwise = Nothing -- otherwise, fail
And the following algebraic data types:
type Key = String
data Json = JObj Key JValue
| Arr [JValue]
deriving Show
data JValue = N Double
| S String
| B Bool
| J Json
deriving Show
I wrote the following function to parse a position JSON number with a decimal point:
parseDecimalPoint :: Parser Char
parseDecimalPoint = satisfy (== '.')
type Whole = Integer
type Decimal = Integer
readWholeAndDecimal :: Whole -> Decimal -> Double
readWholeAndDecimal w d = read $ (show w) ++ "." ++ (show d)
parsePositiveDecimal:: Parser JValue
parsePositiveDecimal = (\x _ y -> f x y) <$> (
(oneOrMore (satisfy isNumber)) <*> parseDecimalPoint <*>
(zeroOrMore (satisfy isNumber)) )
where
f x [] = N (read x)
f x y = N (-(readWholeAndDecimal (read x) (read y)))
However I'm getting the following compile-time error:
JsonParser.hs:30:25:
Couldn't match expected type ‘t0 -> [Char] -> JValue’
with actual type ‘JValue’
The lambda expression ‘\ x _ y -> f x y’ has three arguments,
but its type ‘String -> JValue’ has only one
In the first argument of ‘(<$>)’, namely ‘(\ x _ y -> f x y)’
In the expression:
(\ x _ y -> f x y)
<$>
((oneOrMore (satisfy isNumber)) <*> parseDecimalPoint
<*> (zeroOrMore (satisfy isNumber)))
JsonParser.hs:30:49:
Couldn't match type ‘[Char]’ with ‘Char -> [Char] -> String’
Expected type: Parser (Char -> [Char] -> String)
Actual type: Parser [Char]
In the first argument of ‘(<*>)’, namely
‘(oneOrMore (satisfy isNumber))’
In the first argument of ‘(<*>)’, namely
‘(oneOrMore (satisfy isNumber)) <*> parseDecimalPoint’
In my parsePositiveDecimal function, my understanding of the types are:
(String -> Char -> String -> JValue) <$> (Parser String <*> Parser Char <*> Parser String)
I've worked through a few examples making parsers with <$> and <*>. But I'm not entirely grokking the types.
Any help on understanding them too would be greatly appreciated.
Cactus is correct. I'll expand a bit on the types.
<$> :: Functor f => (a -> b) -> f a -> f b
Our f here is Parser, and the first argument to <$> has type String -> Char -> String -> JValue. Remember that this can be understood as a function which takes a String and returns a function Char -> String -> JValue So the a type variable is filled in with String.
From that, we can see that the second argument to <$> needs to be of type Parser String. oneOrMore (satisfy isNumber) has that type.
Taken together, we now have:
(\x _ y -> f x y) <$> (oneOrMore (satisfy isNumber)) :: Parser (Char -> String -> JValue)
We've gone from a function of 3 arguments which didn't involve Parser at all, to a function of 2 arguments wrapped in Parser. To apply this function to it's next argument, Char, we need:
(<*>) :: Applicative f => f (a -> b) -> f a -> f b
f is Parser again, and a here is Char. parseDecimalPoint :: Parser Char has the required type for the right-hand side of <*>.
(\x _ y -> f x y) <$> (oneOrMore (satisfy isNumber)) <*> parseDecimalPoint :: Parser (String -> JValue)
We do this one more time, to get:
(\x _ y -> f x y) <$> oneOrMore (satisfy isNumber) <*> parseDecimalPoint <*> zeroOrMore (satisfy isNumber) :: Parser JValue
I've taken advantage of knowing the precedence and associativity of the operators to remove some parentheses. This is how I see most such code written, but perhaps Cactus's version is more clear. Or even the fully parenthesized version, emphasizing the associativity:
( ((\x _ y -> f x y) <$>
(oneOrMore (satisfy isNumber)))
<*> parseDecimalPoint)
<*> (zeroOrMore (satisfy isNumber)) :: Parser JValue

Is it possible to express chainl1 using applicative?

Is it possible to express the chainl1 combinator from Parsec not using the Monad instance defined by parsec?
chainl1 p op =
do x <- p
rest x
where
rest x = do f <- op
y <- p
rest (f x y)
<|> return x
Yes, it is:
chainl1 p op = foldl (flip ($)) <$> p <*> many (flip <$> op <*> p)
The idea is that you have to parse p (op p)* and evaluate it as (...(((p) op p) op p)...).
It might help to expand the definition a bit:
chainl1 p op = foldl (\x f -> f x) <$> p <*> many ((\f y -> flip f y) <$> op <*> p)
As the pairs of op and p are parsed, the results are applied immediately, but because p is the right operand of op, it needs a flip.
So, the result type of many (flip <$> op <*> p) is f [a -> a]. This list of functions is then applied from left to right on an initial value of p by foldl.
Ugly but equivalent Applicative definition:
chainl1 p op =
p <**>
rest
where
rest = flip <$> op <*>
p <**>
pure (.) <*> rest
<|> pure id
Instead of passing of left-side argument x explicitly to the right-hand side op, this Applicative form 'chains' op's partially applied to their right-side argument (hence flip <$> op <*> p) via lifted combinator (.) and then applies the leftmost p via (<**>) to the resulting rest :: Alternative f => f (a -> a).

Resources