Skip to content

Commit 20a9b06

Browse files
committed
Merge pull request #7 from purescript-contrib/alternative
Alternative
2 parents a198281 + 9b13ce9 commit 20a9b06

File tree

8 files changed

+70
-73
lines changed

8 files changed

+70
-73
lines changed

bower.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,10 @@
1818
"package.json"
1919
],
2020
"dependencies": {
21-
"purescript-transformers": "*",
21+
"purescript-transformers": "~0.1.0",
2222
"purescript-either": "*",
23-
"purescript-maybe": "*",
24-
"purescript-arrays": "*",
23+
"purescript-maybe": "~0.2.0",
24+
"purescript-arrays": "~0.2.0",
2525
"purescript-strings": "*",
2626
"purescript-foldable-traversable": "*"
2727
}

docs/Module.md

+10-10
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,14 @@
99

1010
type Parser s a = ParserT s Identity a
1111

12-
data ParserT s m a where
12+
newtype ParserT s m a where
1313
ParserT :: s -> m { consumed :: Boolean, result :: Either ParseError a, input :: s } -> ParserT s m a
1414

1515

1616
### Type Class Instances
1717

18+
instance altParserT :: (Monad m) => Alt (ParserT s m)
19+
1820
instance alternativeParserT :: (Monad m) => Alternative (ParserT s m)
1921

2022
instance applicativeParserT :: (Monad m) => Applicative (ParserT s m)
@@ -27,16 +29,22 @@
2729

2830
instance functorParserT :: (Functor m) => Functor (ParserT s m)
2931

32+
instance lazy1ParserT :: Lazy1 (ParserT s m)
33+
3034
instance monadParserT :: (Monad m) => Monad (ParserT s m)
3135

36+
instance monadPlusParserT :: (Monad m) => MonadPlus (ParserT s m)
37+
3238
instance monadStateParserT :: (Monad m) => MonadState s (ParserT s m)
3339

3440
instance monadTransParserT :: MonadTrans (ParserT s)
3541

42+
instance plusParserT :: (Monad m) => Plus (ParserT s m)
43+
3644

3745
### Values
3846

39-
consume :: forall s m. (Monad m) => ParserT s m { }
47+
consume :: forall s m. (Monad m) => ParserT s m Unit
4048

4149
fail :: forall m s a. (Monad m) => String -> ParserT s m a
4250

@@ -73,14 +81,6 @@
7381

7482
endBy1 :: forall m s a sep. (Monad m) => ParserT s m a -> ParserT s m sep -> ParserT s m [a]
7583

76-
fix :: forall m s a. (ParserT m s a -> ParserT m s a) -> ParserT m s a
77-
78-
fix2 :: forall m s a b. (Tuple (ParserT m s a) (ParserT m s b) -> Tuple (ParserT m s a) (ParserT m s b)) -> Tuple (ParserT m s a) (ParserT m s b)
79-
80-
many :: forall m s a. (Monad m) => ParserT s m a -> ParserT s m [a]
81-
82-
many1 :: forall m s a. (Monad m) => ParserT s m a -> ParserT s m [a]
83-
8484
option :: forall m s a. (Monad m) => a -> ParserT s m a -> ParserT s m a
8585

8686
optionMaybe :: forall m s a. (Functor m, Monad m) => ParserT s m a -> ParserT s m (Maybe a)

examples/Test.purs

+19-14
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
module Main where
22

3-
import Prelude
43
import Data.Array
54
import Data.Either
65
import Data.Maybe
6+
7+
import Control.Alt
8+
import Control.Alternative
79
import Control.Monad.Eff
810
import Control.Monad.Identity
11+
import Control.Lazy
12+
913
import Debug.Trace
14+
1015
import Text.Parsing.Parser
1116
import Text.Parsing.Parser.Combinators
1217
import Text.Parsing.Parser.Expr
@@ -16,7 +21,7 @@ parens :: forall m a. (Monad m) => ParserT String m a -> ParserT String m a
1621
parens = between (string "(") (string ")")
1722

1823
nested :: forall m. (Functor m, Monad m) => ParserT String m Number
19-
nested = fix $ \p -> (do
24+
nested = fix1 $ \p -> (do
2025
string "a"
2126
return 0) <|> ((+) 1) <$> parens p
2227

@@ -30,16 +35,16 @@ opTest = chainl char (do string "+"
3035
return (++)) ""
3136

3237
digit :: Parser String Number
33-
digit = (string "0" >>= \_ -> return 0)
34-
<|> (string "1" >>= \_ -> return 1)
35-
<|> (string "2" >>= \_ -> return 2)
36-
<|> (string "3" >>= \_ -> return 3)
37-
<|> (string "4" >>= \_ -> return 4)
38-
<|> (string "5" >>= \_ -> return 5)
39-
<|> (string "6" >>= \_ -> return 6)
40-
<|> (string "7" >>= \_ -> return 7)
41-
<|> (string "8" >>= \_ -> return 8)
42-
<|> (string "9" >>= \_ -> return 9)
38+
digit = (string "0" >>= \_ -> return 0)
39+
<|> (string "1" >>= \_ -> return 1)
40+
<|> (string "2" >>= \_ -> return 2)
41+
<|> (string "3" >>= \_ -> return 3)
42+
<|> (string "4" >>= \_ -> return 4)
43+
<|> (string "5" >>= \_ -> return 5)
44+
<|> (string "6" >>= \_ -> return 6)
45+
<|> (string "7" >>= \_ -> return 7)
46+
<|> (string "8" >>= \_ -> return 8)
47+
<|> (string "9" >>= \_ -> return 9)
4348

4449
exprTest :: Parser String Number
4550
exprTest = buildExprParser [[Infix (string "/" >>= \_ -> return (/)) AssocRight]
@@ -49,7 +54,7 @@ exprTest = buildExprParser [[Infix (string "/" >>= \_ -> return (/)) AssocRight]
4954

5055
manySatisfyTest :: Parser String [String]
5156
manySatisfyTest = do
52-
r <- many1 $ satisfy (\s -> s /= "?")
57+
r <- some $ satisfy (\s -> s /= "?")
5358
string "?"
5459
return r
5560

@@ -63,7 +68,7 @@ main = do
6368
parseTest (do
6469
as <- string "a" `endBy1` string ","
6570
eof
66-
return as) "a,a,a,"
71+
return as) "a,a,a,"
6772
parseTest opTest "a+b+c"
6873
parseTest exprTest "1*2+3/4-5"
6974
parseTest manySatisfyTest "ab?"

src/Text/Parsing/Parser.purs

+23-12
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,23 @@
11
module Text.Parsing.Parser where
22

3-
import Prelude
4-
53
import Data.Either
64
import Data.Maybe
75
import Data.Monoid
86
import Data.Tuple
97

8+
import Control.Alt
9+
import Control.Alternative
10+
import Control.Lazy
1011
import Control.Monad
1112
import Control.Monad.Identity
12-
1313
import Control.Monad.Trans
1414
import Control.Monad.State.Class
1515
import Control.Monad.State.Trans
1616
import Control.Monad.Error
1717
import Control.Monad.Error.Class
1818
import Control.Monad.Error.Trans
19+
import Control.MonadPlus
20+
import Control.Plus
1921

2022
data ParseError = ParseError
2123
{ message :: String
@@ -25,7 +27,7 @@ instance errorParseError :: Error ParseError where
2527
noMsg = ParseError { message: "" }
2628
strMsg msg = ParseError { message: msg }
2729

28-
data ParserT s m a = ParserT (s -> m { input :: s, result :: Either ParseError a, consumed :: Boolean })
30+
newtype ParserT s m a = ParserT (s -> m { input :: s, result :: Either ParseError a, consumed :: Boolean })
2931

3032
unParserT :: forall m s a. ParserT s m a -> s -> m { input :: s, result :: Either ParseError a, consumed :: Boolean }
3133
unParserT (ParserT p) = p
@@ -41,23 +43,27 @@ runParser :: forall s a. s -> Parser s a -> Either ParseError a
4143
runParser s = runIdentity <<< runParserT s
4244

4345
instance functorParserT :: (Functor m) => Functor (ParserT s m) where
44-
(<$>) f p = ParserT $ \s -> f' <$> unParserT p s
46+
(<$>) f p = ParserT $ \s -> f' <$> unParserT p s
4547
where
4648
f' o = { input: o.input, result: f <$> o.result, consumed: o.consumed }
4749

4850
instance applyParserT :: (Monad m) => Apply (ParserT s m) where
4951
(<*>) = ap
50-
52+
5153
instance applicativeParserT :: (Monad m) => Applicative (ParserT s m) where
5254
pure a = ParserT $ \s -> pure { input: s, result: Right a, consumed: false }
53-
54-
instance alternativeParserT :: (Monad m) => Alternative (ParserT s m) where
55-
empty = fail "No alternative"
55+
56+
instance altParserT :: (Monad m) => Alt (ParserT s m) where
5657
(<|>) p1 p2 = ParserT $ \s -> unParserT p1 s >>= \o ->
5758
case o.result of
5859
Left _ | not o.consumed -> unParserT p2 s
5960
_ -> return o
6061

62+
instance plusParserT :: (Monad m) => Plus (ParserT s m) where
63+
empty = fail "No alternative"
64+
65+
instance alternativeParserT :: (Monad m) => Alternative (ParserT s m)
66+
6167
instance bindParserT :: (Monad m) => Bind (ParserT s m) where
6268
(>>=) p f = ParserT $ \s -> unParserT p s >>= \o ->
6369
case o.result of
@@ -68,16 +74,21 @@ instance bindParserT :: (Monad m) => Bind (ParserT s m) where
6874

6975
instance monadParserT :: (Monad m) => Monad (ParserT s m)
7076

77+
instance monadPlusParserT :: (Monad m) => MonadPlus (ParserT s m)
78+
7179
instance monadTransParserT :: MonadTrans (ParserT s) where
7280
lift m = ParserT $ \s -> (\a -> { input: s, consumed: false, result: Right a }) <$> m
7381

7482
instance monadStateParserT :: (Monad m) => MonadState s (ParserT s m) where
75-
state f = ParserT $ \s ->
83+
state f = ParserT $ \s ->
7684
return $ case f s of
7785
Tuple a s' -> { input: s', consumed: false, result: Right a }
7886

79-
consume :: forall s m. (Monad m) => ParserT s m {}
80-
consume = ParserT $ \s -> return { consumed: true, input: s, result: Right {} }
87+
instance lazy1ParserT :: Lazy1 (ParserT s m) where
88+
defer1 f = ParserT $ \s -> unParserT (f unit) s
89+
90+
consume :: forall s m. (Monad m) => ParserT s m Unit
91+
consume = ParserT $ \s -> return { consumed: true, input: s, result: Right unit }
8192

8293
fail :: forall m s a. (Monad m) => String -> ParserT s m a
8394
fail message = ParserT $ \s -> return { input: s, consumed: false, result: Left (ParseError { message: message }) }

src/Text/Parsing/Parser/Combinators.purs

+6-22
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,29 @@
11
module Text.Parsing.Parser.Combinators where
22

3-
import Prelude
4-
53
import Data.Maybe
64
import Data.Array
75
import Data.Tuple
86
import Data.Either
97

8+
import Control.Alt
9+
import Control.Alternative
10+
import Control.Lazy
1011
import Control.Monad
11-
1212
import Control.Monad.Error.Trans
1313
import Control.Monad.Error.Class
1414
import Control.Monad.State.Trans
1515
import Control.Monad.State.Class
1616

1717
import Text.Parsing.Parser
1818

19-
fix :: forall m s a. (ParserT m s a -> ParserT m s a) -> ParserT m s a
20-
fix f = ParserT $ \s -> unParserT (f (fix f)) s
21-
22-
fix2 :: forall m s a b. (Tuple (ParserT m s a) (ParserT m s b) -> Tuple (ParserT m s a) (ParserT m s b)) -> Tuple (ParserT m s a) (ParserT m s b)
23-
fix2 f = Tuple
24-
(ParserT $ \s -> unParserT (fst (f (fix2 f))) s)
25-
(ParserT $ \s -> unParserT (snd (f (fix2 f))) s)
26-
27-
many :: forall m s a. (Monad m) => ParserT s m a -> ParserT s m [a]
28-
many p = many1 p <|> return []
29-
30-
many1 :: forall m s a. (Monad m) => ParserT s m a -> ParserT s m [a]
31-
many1 p = do a <- p
32-
as <- many p
33-
return (a : as)
34-
3519
(<?>) :: forall m s a. (Monad m) => ParserT s m a -> String -> ParserT s m a
3620
(<?>) p msg = p <|> fail ("Expected " ++ msg)
3721

3822
between :: forall m s a open close. (Monad m) => ParserT s m open -> ParserT s m close -> ParserT s m a -> ParserT s m a
3923
between open close p = do
4024
open
4125
a <- p
42-
close
26+
close
4327
return a
4428

4529
option :: forall m s a. (Monad m) => a -> ParserT s m a -> ParserT s m a
@@ -54,7 +38,7 @@ optionMaybe p = option Nothing (Just <$> p)
5438

5539
try :: forall m s a. (Functor m) => ParserT s m a -> ParserT s m a
5640
try p = ParserT $ \s -> try' s <$> unParserT p s
57-
where
41+
where
5842
try' s o@{ result = Left _ } = { input: s, result: o.result, consumed: false }
5943
try' _ o = o
6044

@@ -80,7 +64,7 @@ sepEndBy1 p sep = do
8064
return (a : as)) <|> return [a]
8165

8266
endBy1 :: forall m s a sep. (Monad m) => ParserT s m a -> ParserT s m sep -> ParserT s m [a]
83-
endBy1 p sep = many1 $ do
67+
endBy1 p sep = some $ do
8468
a <- p
8569
sep
8670
return a

src/Text/Parsing/Parser/Expr.purs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
module Text.Parsing.Parser.Expr where
22

3-
import Prelude
4-
53
import Data.Either
64
import Data.Foldable
75

6+
import Control.Alt
7+
88
import Text.Parsing.Parser
99
import Text.Parsing.Parser.Combinators
1010

src/Text/Parsing/Parser/String.purs

+7-8
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,33 @@
11
module Text.Parsing.Parser.String where
22

3-
import Prelude
4-
53
import Data.String
64
import Data.Either
5+
import Data.Foldable
6+
import Data.Monoid
77

8+
import Control.Alt
9+
import Control.Alternative
810
import Control.Monad.Error
911
import Control.Monad.Error.Class
1012
import Control.Monad.State.Class
1113

12-
import Data.Foldable
13-
import Data.Monoid
14-
1514
import Text.Parsing.Parser
1615
import Text.Parsing.Parser.Combinators
1716

1817
eof :: forall m. (Monad m) => ParserT String m {}
19-
eof = ParserT $ \s ->
18+
eof = ParserT $ \s ->
2019
return $ case s of
2120
"" -> { consumed: false, input: s, result: Right {} }
2221
_ -> { consumed: false, input: s, result: Left (strMsg "Expected EOF") }
2322

2423
string :: forall m. (Monad m) => String -> ParserT String m String
25-
string s = ParserT $ \s' ->
24+
string s = ParserT $ \s' ->
2625
return $ case indexOf s s' of
2726
0 -> { consumed: true, input: drop (length s) s', result: Right s }
2827
_ -> { consumed: false, input: s', result: Left (strMsg ("Expected " ++ show s)) }
2928

3029
char :: forall m. (Monad m) => ParserT String m String
31-
char = ParserT $ \s' ->
30+
char = ParserT $ \s' ->
3231
return $ case s' of
3332
"" -> { consumed: false, input: s', result: Left (strMsg "Unexpected EOF") }
3433
_ -> { consumed: true, input: drop 1 s', result: Right (charAt 0 s') }

src/Text/Parsing/Parser/Token.purs

-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
module Text.Parsing.Parser.Token where
22

3-
import Prelude
4-
53
import Data.String
64

75
import Control.Monad.State.Class

0 commit comments

Comments
 (0)