Skip to content

Commit ab141f0

Browse files
committed
Add fix combinator
1 parent 2df0d8f commit ab141f0

File tree

2 files changed

+13
-10
lines changed

2 files changed

+13
-10
lines changed

examples/test.purs.hs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,13 @@ import Text.Parsing.Parser.Combinators
1212
import Text.Parsing.Parser.Expr
1313
import Text.Parsing.Parser.String
1414

15-
parens :: forall m a. (Monad m) => ({} -> ParserT String m a) -> ParserT String m a
15+
parens :: forall m a. (Monad m) => ParserT String m a -> ParserT String m a
1616
parens = between (string "(") (string ")")
1717

18-
nested :: forall m. (Monad m) => {} -> ParserT String m Number
19-
nested _ = (do
18+
nested :: forall m. (Monad m) => ParserT String m Number
19+
nested = fix $ \p -> (do
2020
string "a"
21-
return 0) <|> ((+) 1) <$> parens nested
21+
return 0) <|> ((+) 1) <$> parens p
2222

2323
parseTest :: forall s a eff. (Show a) => Parser s a -> s -> Eff (trace :: Trace | eff) {}
2424
parseTest p input = case runParser input p of
@@ -46,11 +46,11 @@ exprTest = buildExprParser [[Infix (string "/" >>= \_ -> return (/)) AssocRight]
4646
,[Infix (string "*" >>= \_ -> return (*)) AssocRight]
4747
,[Infix (string "-" >>= \_ -> return (-)) AssocRight]
4848
,[Infix (string "+" >>= \_ -> return (+)) AssocRight]] digit
49-
49+
5050
main = do
51-
parseTest (nested {}) "(((a)))"
51+
parseTest nested "(((a)))"
5252
parseTest (many (string "a")) "aaa"
53-
parseTest (parens (const $ do
53+
parseTest (parens (do
5454
string "a"
5555
optionMaybe $ string "b")) "(ab)"
5656
parseTest (string "a" `sepBy1` string ",") "a,a,a"

src/Text/Parsing/Parser/Combinators.purs.hs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ import Control.Monad.State.Class
1515

1616
import Text.Parsing.Parser
1717

18+
fix :: forall m s a. (ParserT m s a -> ParserT m s a) -> ParserT m s a
19+
fix f = ParserT (StateT (\s -> runStateT (unParserT (f (fix f))) s))
20+
1821
many :: forall m s a. (Monad m) => ParserT s m a -> ParserT s m [a]
1922
many p = many1 p <|> return []
2023

@@ -24,12 +27,12 @@ many1 p = do a <- p
2427
return (a : as)
2528

2629
(<?>) :: forall m s a. (Monad m) => ParserT s m a -> String -> ParserT s m a
27-
(<?>) p msg = p <|> fail msg
30+
(<?>) p msg = p <|> fail ("Expected " ++ msg)
2831

29-
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
32+
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
3033
between open close p = do
3134
open
32-
a <- p {}
35+
a <- p
3336
close
3437
return a
3538

0 commit comments

Comments
 (0)