@@ -5,4 +5,108 @@ title: Appar
55
66{% include toc.html %}
77
8- https://hackage.haskell.org/package/appar
8+ [ Appar] ( https://hackage.haskell.org/package/appar ) is different from the other
9+ libraries such that, they are monadic, while ` appar ` is applicative.
10+ See [ this] ( https://stackoverflow.com/a/7863380/1599054 ) to have a good explanation
11+ between the two.
12+
13+ # Definition
14+
15+ Let's start with the definition:
16+
17+ ``` haskell
18+ data MkParser inp a = P {
19+ runParser :: inp -> (Maybe a , inp )
20+ }
21+ ```
22+
23+ It really looks like `attoparsec` 's `ZeptoT `, except that the `Monad ` is inside
24+ the result.
25+
26+ Let's see the instances:
27+
28+ ```haskell
29+ instance Functor (MkParser inp ) where
30+ f `fmap` p = return f <*> p
31+
32+ instance Applicative (MkParser inp ) where
33+ pure a = P $ \ bs -> (Just a, bs)
34+ (<*>) = ap
35+
36+ instance Alternative (MkParser inp ) where
37+ empty = mzero
38+ (<|>) = mplus
39+
40+ instance Monad (MkParser inp ) where
41+ return = pure
42+ p >>= f = P $ \ bs -> case runParser p bs of
43+ (Nothing , bs') -> (Nothing , bs')
44+ (Just a, bs') -> runParser (f a) bs'
45+
46+ instance MonadPlus (MkParser inp ) where
47+ mzero = P $ \ bs -> (Nothing , bs)
48+ p `mplus` q = P $ \ bs -> case runParser p bs of
49+ (Nothing , bs') -> runParser q bs'
50+ (Just a, bs') -> (Just a, bs')
51+ ```
52+
53+ One thing surprising is the ` Monad ` instance for an applicative parser, we can
54+ conclude that the '` Applicative ` ness' of the library cames from the lack of
55+ shortcut, more than the implemented solution.
56+
57+ # Construction
58+
59+ How are parsers built:
60+
61+ ``` haskell
62+ class Eq inp => Input inp where
63+ -- | The head function for input
64+ car :: inp -> Char
65+ -- | The tail function for input
66+ cdr :: inp -> inp
67+ -- | The end of input
68+ nil :: inp
69+ -- | The function to check the end of input
70+ isNil :: inp -> Bool
71+
72+ satisfy :: Input inp => (Char -> Bool ) -> MkParser inp Char
73+ satisfy predicate = P sat
74+ where
75+ sat bs
76+ | isNil bs = (Nothing , nil)
77+ | predicate b = (Just b, bs')
78+ | otherwise = (Nothing , bs)
79+ where
80+ b = car bs
81+ bs' = cdr bs
82+ ```
83+
84+ A bit abstract (and a bit lisp-like), but without surprises.
85+
86+ Anothor interesting one:
87+
88+ ``` haskell
89+ try :: MkParser inp a -> MkParser inp a
90+ try p = P $ \ bs -> case runParser p bs of
91+ (Nothing , _ ) -> (Nothing , bs)
92+ (Just a, bs') -> (Just a, bs')
93+ ```
94+
95+ As expected: the parser is ran, if it succeeds, the input is consumer, or the
96+ original input is returned.
97+
98+ # Running the parser
99+
100+ As we can expect, running the pparser will only consist in getting the computed
101+ result:
102+
103+ ``` haskell
104+ parse :: Input inp => MkParser inp a -> inp -> Maybe a
105+ parse p bs = fst (runParser p bs)
106+ ```
107+
108+ # Conclusion
109+
110+ ` appar ` is really simple, but it is unique in the sense that it prevent
111+ context-dependant parsing.
112+
0 commit comments