Skip to content

Commit ca18481

Browse files
committed
Add Monad instance for Parser newtype
1 parent 41cb79a commit ca18481

File tree

2 files changed

+45
-0
lines changed

2 files changed

+45
-0
lines changed
File renamed without changes.
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import Control.Applicative
2+
import Data.Char
3+
4+
newtype Parser a = P (String -> [(a, String)])
5+
6+
parse :: Parser a -> String -> [(a, String)]
7+
parse (P p) inp = p inp
8+
9+
item :: Parser Char
10+
item = P $ \inp ->
11+
case inp of
12+
[] -> []
13+
(x:xs) -> [(x, xs)]
14+
15+
instance Functor Parser where
16+
fmap f p = P $ \inp ->
17+
case parse p inp of
18+
[] -> []
19+
[(v, out)] -> [(f v, out)]
20+
21+
instance Applicative Parser where
22+
pure v = P $ \inp -> [(v, inp)]
23+
24+
pf <*> px = P $ \inp ->
25+
case parse pf inp of
26+
[] -> []
27+
[(f, out)] -> parse (fmap f px) out
28+
29+
three :: Parser (Char, Char)
30+
three = pure f <*> item <*> item <*> item
31+
where
32+
f x y z = (x, z)
33+
34+
instance Monad Parser where
35+
p >>= f = P $ \inp ->
36+
case parse p inp of
37+
[] -> []
38+
[(v, out)] -> parse (f v) out
39+
40+
three' :: Parser (Char, Char)
41+
three' = do
42+
x <- item
43+
item
44+
z <- item
45+
return (x, z)

0 commit comments

Comments
 (0)