|
| 1 | + |
| 2 | +module Bugs.Bug179 |
| 3 | + ( tests |
| 4 | + ) where |
| 5 | + |
| 6 | +import Control.Applicative (Alternative (..), liftA2, (<|>)) |
| 7 | +import Test.Tasty ( testGroup, TestTree ) |
| 8 | +import Test.Tasty.HUnit |
| 9 | + |
| 10 | +import qualified Control.Applicative |
| 11 | +import qualified Text.Parsec as P |
| 12 | +import qualified Text.Parsec.String as P |
| 13 | + |
| 14 | +tests :: TestTree |
| 15 | +tests = testGroup "many try (#179)" |
| 16 | + [ testCase "manyDefault" $ examples parser1 |
| 17 | + , testCase "C.Applicative" $ examples parser2 |
| 18 | + , testCase "Parsec" $ examples parser3 |
| 19 | + ] |
| 20 | + where |
| 21 | + examples p = do |
| 22 | + res1 <- parseString p $ unlines [" ", " ", "foo"] |
| 23 | + res1 @?= "foo\n" |
| 24 | + |
| 25 | + res2 <- parseString p $ unlines ["bar"] |
| 26 | + res2 @?= "bar\n" |
| 27 | + |
| 28 | + res3 <- parseString p $ unlines [" ", " ", " foo"] |
| 29 | + res3 @?= " foo\n" |
| 30 | + |
| 31 | + res4 <- parseString p $ unlines [" bar"] |
| 32 | + res4 @?= " bar\n" |
| 33 | + |
| 34 | + parseString :: P.Parser String -> String -> IO String |
| 35 | + parseString p input = |
| 36 | + case P.parse p "" input of |
| 37 | + Left err -> assertFailure $ show err |
| 38 | + Right str -> return str |
| 39 | + |
| 40 | +parser1 :: P.Parser String |
| 41 | +parser1 = emptyLines *> P.getInput where |
| 42 | + emptyLines :: P.Parser String |
| 43 | + emptyLines = manyDefault $ P.try $ P.skipMany (P.satisfy (== ' ')) *> P.char '\n' |
| 44 | + |
| 45 | +parser2 :: P.Parser String |
| 46 | +parser2 = emptyLines *> P.getInput where |
| 47 | + emptyLines :: P.Parser String |
| 48 | + emptyLines = Control.Applicative.many $ P.try $ P.skipMany (P.satisfy (== ' ')) *> P.char '\n' |
| 49 | + |
| 50 | +parser3 :: P.Parser String |
| 51 | +parser3 = emptyLines *> P.getInput where |
| 52 | + emptyLines :: P.Parser String |
| 53 | + emptyLines = P.many $ P.try $ P.skipMany (P.satisfy (== ' ')) *> P.char '\n' |
| 54 | + |
| 55 | +-- many's default definition |
| 56 | +manyDefault :: Alternative f => f a -> f [a] |
| 57 | +manyDefault v = many_v |
| 58 | + where |
| 59 | + many_v = some_v <|> pure [] |
| 60 | + some_v = liftA2 (:) v many_v |
0 commit comments