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