Clean up function names
Also create separate showExpression function
This commit is contained in:
parent
fec6dcb7cf
commit
46d74f73f2
1 changed files with 46 additions and 34 deletions
60
lambda.hs
60
lambda.hs
|
|
@ -1,3 +1,10 @@
|
||||||
|
-- module Lambda
|
||||||
|
-- ( Expression
|
||||||
|
-- , showExpression
|
||||||
|
-- , maybeParseExpression
|
||||||
|
-- , evaluateExpression
|
||||||
|
-- ) where
|
||||||
|
|
||||||
import Control.Monad
|
import Control.Monad
|
||||||
import Data.List
|
import Data.List
|
||||||
import Data.Maybe
|
import Data.Maybe
|
||||||
|
|
@ -11,6 +18,24 @@ data Expression s = ESymbol s
|
||||||
| EReference Int
|
| EReference Int
|
||||||
| EExpr (Expression s) (Expression s)
|
| EExpr (Expression s) (Expression s)
|
||||||
| ELambda s (Expression s)
|
| ELambda s (Expression s)
|
||||||
|
deriving (Show)
|
||||||
|
|
||||||
|
instance (Eq s) => Eq (Expression s) where
|
||||||
|
(ESymbol a) == (ESymbol b) = a == b
|
||||||
|
(EReference a) == (EReference b) = a == b
|
||||||
|
(EExpr a b) == (EExpr c d) = a == c && b == d
|
||||||
|
(ELambda _ a) == (ELambda _ b) = a == b
|
||||||
|
_ == _ = False
|
||||||
|
|
||||||
|
instance Functor Expression where
|
||||||
|
fmap f (EReference n) = EReference n
|
||||||
|
fmap f (ESymbol a) = ESymbol (f a)
|
||||||
|
fmap f (ELambda s e) = ELambda (f s) (fmap f e)
|
||||||
|
fmap f (EExpr a b) = EExpr (fmap f a) (fmap f b)
|
||||||
|
|
||||||
|
{-
|
||||||
|
- Displaying expressions
|
||||||
|
-}
|
||||||
|
|
||||||
-- list of names -> name -> unique name
|
-- list of names -> name -> unique name
|
||||||
-- Find a unique name not in the list of names.
|
-- Find a unique name not in the list of names.
|
||||||
|
|
@ -32,14 +57,14 @@ renameUniquely = rename_ []
|
||||||
rename_ c (ELambda s e) = let name = makeUnique c . show $ s
|
rename_ c (ELambda s e) = let name = makeUnique c . show $ s
|
||||||
in ELambda name (rename_ (name : c) e)
|
in ELambda name (rename_ (name : c) e)
|
||||||
|
|
||||||
instance (Show s) => Show (Expression s) where
|
showExpression :: (Show s) => Bool -> Expression s -> String
|
||||||
show = show_ [] . renameUniquely
|
showExpression unicode = show_ [] . renameUniquely
|
||||||
-- show_ :: Expression String -> String
|
|
||||||
where show_ c (EReference n)
|
where show_ c (EReference n)
|
||||||
| n >= 0 && n < length c = c !! n
|
| n >= 0 && n < length c = c !! n
|
||||||
| otherwise = "ERR" -- TODO: Deal with errors properly?
|
| otherwise = "ERR" -- TODO: Deal with errors properly?
|
||||||
show_ c (ESymbol s) = s
|
show_ c (ESymbol s) = s
|
||||||
show_ c (ELambda s e) = "\\" ++ s ++ "." ++ show_ (s : c) e
|
show_ c (ELambda s e) = (if unicode then "λ" else "\\")
|
||||||
|
++ s ++ "." ++ show_ (s : c) e
|
||||||
show_ c (EExpr a@(ELambda _ _) b@(ELambda _ _)) = "(" ++ show_ c a ++ ") (" ++ show_ c b ++ ")"
|
show_ c (EExpr a@(ELambda _ _) b@(ELambda _ _)) = "(" ++ show_ c a ++ ") (" ++ show_ c b ++ ")"
|
||||||
show_ c (EExpr a@(ELambda _ _) b@(EExpr _ _)) = "(" ++ show_ c a ++ ") (" ++ show_ c b ++ ")"
|
show_ c (EExpr a@(ELambda _ _) b@(EExpr _ _)) = "(" ++ show_ c a ++ ") (" ++ show_ c b ++ ")"
|
||||||
show_ c (EExpr a@(ELambda _ _) b ) = "(" ++ show_ c a ++ ") " ++ show_ c b
|
show_ c (EExpr a@(ELambda _ _) b ) = "(" ++ show_ c a ++ ") " ++ show_ c b
|
||||||
|
|
@ -47,19 +72,6 @@ instance (Show s) => Show (Expression s) where
|
||||||
show_ c (EExpr a b@(EExpr _ _)) = show_ c a ++ " (" ++ show_ c b ++ ")"
|
show_ c (EExpr a b@(EExpr _ _)) = show_ c a ++ " (" ++ show_ c b ++ ")"
|
||||||
show_ c (EExpr a b) = show_ c a ++ " " ++ show_ c b
|
show_ c (EExpr a b) = show_ c a ++ " " ++ show_ c b
|
||||||
|
|
||||||
instance (Eq s) => Eq (Expression s) where
|
|
||||||
(ESymbol a) == (ESymbol b) = a == b
|
|
||||||
(EReference a) == (EReference b) = a == b
|
|
||||||
(EExpr a b) == (EExpr c d) = a == c && b == d
|
|
||||||
(ELambda _ a) == (ELambda _ b) = a == b
|
|
||||||
_ == _ = False
|
|
||||||
|
|
||||||
instance Functor Expression where
|
|
||||||
fmap f (EReference n) = EReference n
|
|
||||||
fmap f (ESymbol a) = ESymbol (f a)
|
|
||||||
fmap f (ELambda s e) = ELambda (f s) (fmap f e)
|
|
||||||
fmap f (EExpr a b) = EExpr (fmap f a) (fmap f b)
|
|
||||||
|
|
||||||
{-
|
{-
|
||||||
- Evaluating expressions
|
- Evaluating expressions
|
||||||
-}
|
-}
|
||||||
|
|
@ -85,8 +97,8 @@ takeWhileUnique l = map fst
|
||||||
$ takeWhile (\a -> not $ fst a `elem` snd a)
|
$ takeWhile (\a -> not $ fst a `elem` snd a)
|
||||||
$ zip l (inits l)
|
$ zip l (inits l)
|
||||||
|
|
||||||
evaluate :: (Eq s) => Expression s -> [Expression s]
|
evaluateExpression :: (Eq s) => Expression s -> [Expression s]
|
||||||
evaluate = takeWhileUnique . iterate apply
|
evaluateExpression = takeWhileUnique . iterate apply
|
||||||
|
|
||||||
{-
|
{-
|
||||||
- Parsing expressions
|
- Parsing expressions
|
||||||
|
|
@ -174,14 +186,14 @@ instance Eq StrSymbol where
|
||||||
linewise :: (String -> String) -> String -> String
|
linewise :: (String -> String) -> String -> String
|
||||||
linewise f = unlines . map f . lines
|
linewise f = unlines . map f . lines
|
||||||
|
|
||||||
evaluateExpression :: String -> String
|
evaluate :: String -> String
|
||||||
evaluateExpression s =
|
evaluate s =
|
||||||
let result = return
|
let result = return
|
||||||
. map show
|
. map (showExpression True)
|
||||||
. evaluate
|
. evaluateExpression
|
||||||
. fmap StrSymbol
|
. fmap StrSymbol
|
||||||
l = fromMaybe ["Error: Could not parse expression."]
|
l = fromMaybe ["Error: Could not parse expression."]
|
||||||
$ maybeParseExpression s >>= result
|
$ maybeParseExpression s >>= result
|
||||||
in unlines l
|
in unlines l
|
||||||
|
|
||||||
main = interact $ linewise evaluateExpression
|
main = interact $ linewise evaluate
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue