{---- Monadic parser for a simple lambda calculus using offside rule for let declarations. ---- } module LambdaOff where import MonParserOff import LexingOff -- -- lambda calculus parser -- data Expr = App Expr Expr | Lam String Expr | Let [(String, Expr)] Expr | Var String deriving Show expr = atom `chainl1` (return App) atom = lam +++ local +++ var +++ paren lam = do symbol "\\" x <- variable symbol "->" e <- expr return $ Lam x e local = do symbol "let" ds <- many1_offside defn symbol "in" e' <- expr return $ Let ds e' var = do x <- variable return $ Var x defn = do x <- variable symbol "=" e <- expr return $ (x, e) paren = bracket (symbol "(") expr (symbol ")") variable = identifier ["let", "in"] e0 = "\\x -> let x1 = \\x -> x\n" ++ " x2 = \\f -> \\x -> f x\n" ++ " in x2 (x1 x)\n" e1 = "\\x -> let x1 = \\x -> x; x = x1;\n" ++ " x2 = \\f -> \\x -> \n" ++ " f x\n" ++ " (g x y)\n" ++ " x3 = \\f -> \\x -> f x\n" ++ " in x2 (x1 x)\n"