diff options
| author | Arnaud Bailly <arnaud@pankzsoft.com> | 2025-10-17 16:54:43 +0200 |
|---|---|---|
| committer | Arnaud Bailly <arnaud@pankzsoft.com> | 2025-10-17 16:54:43 +0200 |
| commit | 0837921dae14ec7f1e6008f1f85cbd056ad2aced (patch) | |
| tree | 61f6f73feead72ca3ec5dbe67196f9b43f12019b | |
| parent | 3b20f8a9e85696b86f698e1bdbdbd31b786b77c2 (diff) | |
| download | lambda-nantes-0837921dae14ec7f1e6008f1f85cbd056ad2aced.tar.gz | |
feat: parse an application
| -rw-r--r-- | lambda-calcul/haskell/src/Minilang/Lambda/Parser.hs | 4 | ||||
| -rw-r--r-- | lambda-calcul/haskell/test/Minilang/Lambda/ParserSpec.hs | 15 |
2 files changed, 13 insertions, 6 deletions
diff --git a/lambda-calcul/haskell/src/Minilang/Lambda/Parser.hs b/lambda-calcul/haskell/src/Minilang/Lambda/Parser.hs index e60d761..f18ac74 100644 --- a/lambda-calcul/haskell/src/Minilang/Lambda/Parser.hs +++ b/lambda-calcul/haskell/src/Minilang/Lambda/Parser.hs @@ -13,7 +13,7 @@ type Parser = Parsec Void Text data ParseError = ParseError Text deriving (Eq, Show) -data AST = Sym Text | Abs [Text] AST | App AST AST +data AST = Sym Text | Abs [Text] AST | App AST AST [AST] deriving (Eq, Show) parse :: Text -> Either ParseError AST @@ -28,7 +28,7 @@ app = between lpar rpar - (App <$> ast <*> ast) + (App <$> ast <*> ast <*> many ast) lambda :: Parser AST lambda = diff --git a/lambda-calcul/haskell/test/Minilang/Lambda/ParserSpec.hs b/lambda-calcul/haskell/test/Minilang/Lambda/ParserSpec.hs index b52017a..13279e9 100644 --- a/lambda-calcul/haskell/test/Minilang/Lambda/ParserSpec.hs +++ b/lambda-calcul/haskell/test/Minilang/Lambda/ParserSpec.hs @@ -5,7 +5,7 @@ import qualified Data.Text as Text import Minilang.Lambda.Parser (AST (..), initialChars, parse, restChars) import Test.Hspec (Spec, parallel, shouldBe) import Test.Hspec.QuickCheck (prop) -import Test.QuickCheck (Arbitrary (..), NonEmptyList (..), elements, listOf) +import Test.QuickCheck (Arbitrary (..), NonEmptyList (..), elements, listOf, (==>)) spec :: Spec spec = parallel $ do @@ -17,11 +17,18 @@ spec = parallel $ do prop "parses a lambda-expression with multiple bindings as an abstraction" $ \(NonEmpty idents) (Identifier body) -> let vars = unIdent <$> idents - nestedAbs = Abs vars (Sym body) - in parse ("(lam (" <> Text.unwords vars <> ") " <> body <> ")") `shouldBe` Right nestedAbs + abs = Abs vars (Sym body) + in parse ("(lam (" <> Text.unwords vars <> ") " <> body <> ")") `shouldBe` Right abs prop "parses an application" $ \(Identifier ident1) (Identifier ident2) -> - parse ("(" <> ident1 <> " " <> ident2 <> ")") `shouldBe` Right (App (Sym ident1) (Sym ident2)) + parse ("(" <> ident1 <> " " <> ident2 <> ")") `shouldBe` Right (App (Sym ident1) (Sym ident2) []) + + prop "parses multiple applications" $ \(NonEmpty idents) -> + (length idents >= 2) ==> + let vars = unIdent <$> idents + (a : b : rest) = vars + app = App (Sym a) (Sym b) (Sym <$> rest) + in parse ("(" <> Text.unwords vars <> ")") `shouldBe` Right app newtype Identifier = Identifier {unIdent :: Text} deriving (Eq, Show) |
