Skip to content

Commit 5a3fd8f

Browse files
committed
[lambda] to applicative parser
1 parent 552908c commit 5a3fd8f

File tree

1 file changed

+52
-52
lines changed

1 file changed

+52
-52
lines changed

lambda/Parse.hs

+52-52
Original file line numberDiff line numberDiff line change
@@ -2,88 +2,88 @@
22
{-# LANGUAGE OverloadedStrings #-}
33
module Parse() where
44

5-
import Prelude hiding (map)
65
import Data.Char(isSpace)
76
import qualified Syntax
87
import qualified Data.Maybe as Maybe
98
import Data.Function((&))
9+
import Control.Applicative(Alternative, (<|>))
1010
import qualified Data.ByteString.Char8 as B
1111

12-
type Parser a
13-
= B.ByteString -> Maybe (a, B.ByteString)
12+
newtype Parser a =
13+
Parser { runParser :: B.ByteString -> Maybe (a, B.ByteString) }
14+
15+
instance Functor Parser where
16+
fmap f (Parser parser) =
17+
Parser $ \input ->
18+
case parser input of
19+
Nothing -> Nothing
20+
Just (a, remainder) -> Just (f a, remainder)
21+
22+
instance Applicative Parser where
23+
pure x =
24+
Parser $ \input ->
25+
Just (x, input)
26+
27+
(Parser pFunc) <*> (Parser pArg) =
28+
Parser $ \input -> do
29+
(func, remainder1) <- pFunc input
30+
(arg, remainder2) <- pArg remainder1
31+
return (func arg, remainder2)
32+
33+
instance Alternative Parser where
34+
(Parser p1) <|> (Parser p2) =
35+
Parser $ \input ->
36+
(p1 input) <|> (p2 input)
1437

1538
loc :: Syntax.Location
1639
loc = Syntax.Location 0
1740

1841
string :: B.ByteString -> Parser ()
1942
string str =
20-
\input ->
43+
Parser $ \input ->
2144
case B.stripPrefix str input of
2245
Nothing -> Nothing
2346
Just remainder -> Just ((), remainder)
2447

25-
oneOf :: [Parser a] -> Parser a
26-
oneOf parsers =
27-
\input ->
28-
parsers
29-
& Maybe.mapMaybe ($ input)
30-
& Maybe.listToMaybe
31-
32-
bind :: Parser a -> (a -> Parser b) -> Parser b
33-
bind parser f =
34-
\input ->
35-
case parser input of
36-
Nothing -> Nothing
37-
Just (a, remainder) ->
38-
(f a) remainder
39-
40-
map :: (a -> b) -> Parser a -> Parser b
41-
map f parser =
42-
\input ->
43-
case parser input of
44-
Nothing -> Nothing
45-
Just (a, remainder) ->
46-
Just (f a, remainder)
47-
48-
unit :: a -> Parser a
49-
unit a =
50-
\input -> Just (a, input)
51-
5248
whitespace :: Parser ()
5349
whitespace =
54-
\input ->
50+
Parser $ \input ->
5551
let
5652
(spaces, remainder) = B.span isSpace input
5753
in
58-
if B.null spaces then Nothing else Just ((), remainder)
54+
if B.null spaces
55+
then Nothing
56+
else Just ((), remainder)
5957

6058
term :: Parser Syntax.Term
6159
term =
62-
oneOf
63-
[ literalTrue
64-
, literalFalse
65-
, if_
66-
]
60+
literalTrue
61+
<|> literalFalse
62+
<|> if_
6763

6864
literalTrue :: Parser Syntax.Term
6965
literalTrue =
70-
map (const $ Syntax.True_ loc) (string "true")
66+
fmap (const $ Syntax.True_ loc) (string "true")
7167

7268
literalFalse :: Parser Syntax.Term
7369
literalFalse =
74-
map (const $ Syntax.False_ loc) (string "false")
70+
fmap (const $ Syntax.False_ loc) (string "false")
7571

7672
if_ :: Parser Syntax.Term
7773
if_ =
78-
string "if" `bind` \_ ->
79-
whitespace `bind` \_ ->
80-
term `bind` \condTerm ->
81-
whitespace `bind` \_ ->
82-
string "then" `bind` \_ ->
83-
whitespace `bind` \_ ->
84-
term `bind` \thenTerm ->
85-
whitespace `bind` \_ ->
86-
string "else" `bind` \_ ->
87-
whitespace `bind` \_ ->
88-
term `bind` \elseTerm ->
89-
unit (Syntax.If loc condTerm thenTerm elseTerm)
74+
let
75+
f _ _ condTerm _ _ _ thenTerm _ _ _ elseTerm =
76+
Syntax.If loc condTerm thenTerm elseTerm
77+
in
78+
f
79+
<$> string "if"
80+
<*> whitespace
81+
<*> term
82+
<*> whitespace
83+
<*> string "then"
84+
<*> whitespace
85+
<*> term
86+
<*> whitespace
87+
<*> string "else"
88+
<*> whitespace
89+
<*> term

0 commit comments

Comments
 (0)