2 -fno-warn-unused-do-bind
5 {-# LANGUAGE PatternSynonyms #-}
8 -- Module : Lambda.Parser.Fancy
9 -- Copyright : Tomáš Musil 2014
12 -- Maintainer : tomik.musil@gmail.com
13 -- Stability : experimental
15 -- Parser for λ-terms. '.' in λ implies brackets to the end of the context.
17 -- TODO: proper documentation
19 module Lambda.Parser.Fancy
24 import Data.Text as T hiding (map)
25 import Data.Attoparsec.Text
26 import Control.Applicative
31 -- >>> import Test.QuickCheck
32 -- >>> import Test.Term
35 -- >>> print $ Lambda "x" (Var "x")
38 instance Show Term where
40 show (EmLambda x y t) = show (Lambda (x ++ " " ++ y) t)
41 show (Lambda x t) = "(λ" ++ x ++ "." ++ show t ++ ")"
42 show (AppApp a b c) = show a ++ " " ++ braced (App b c)
43 show (App t r) = show t ++ " " ++ show r
45 braced :: Term -> String
46 braced t = "(" ++ show t ++ ")"
49 -- prop> t == tRead (show (t :: Term))
51 tRead :: String -> Term
52 tRead s = case parseOnly (parseTerm <* endOfInput) (T.pack s) of
56 parseVar :: Parser Term
58 x <- many1 (letter <|> digit)
61 parseLambda :: Parser Term
63 char '\\' <|> char 'λ'
64 vars <- sepBy1 parseVar (char ' ')
67 return $! createLambda vars t
69 parseApp :: Parser Term
71 aps <- sepBy1 (parseBraces <|> parseLambda <|> parseVar) (char ' ')
72 return $! createApp aps
74 parseBraces :: Parser Term
81 parseTerm :: Parser Term
82 parseTerm = parseApp <|>
87 createLambda :: [Term] -> Term -> Term
88 createLambda (Var x : vs) t = Lambda x $ createLambda vs t
90 createLambda _ _ = error "createLambda failed"
92 createApp :: [Term] -> Term
94 createApp (t:ts:tss) = createApp (App t ts : tss)
95 createApp [] = error "empty createApp"