module Language.Sifflet.Examples
(exampleFunctions
, exampleFunctionNames
, exampleEnv
, foo, eFoo
, eMax
, eFact
, getExampleFunction
)
where
import Language.Sifflet.Expr
grossProfit :: Function
grossProfit =
Function (Just "grossProfit") [typeNum, typeNum] typeNum
(Compound ["salesA", "salesB"]
(eCall "+" [eCall "*" [eFloat 0.12, eSymbol "salesA"],
eCall "*" [eFloat 0.25, eSymbol "salesB"]]))
bonus1 :: Function
bonus1 =
Function (Just "bonus1") [typeNum] typeNum
(Compound ["profit"]
(eIf (eCall ">" [eSymbol "profit", eInt 100000])
(eCall "+" [eInt 1000,
eCall "*" [eFloat 0.0012, eSymbol "profit"]])
(eInt 0)))
bonus2 :: Function
bonus2 =
Function (Just "bonus2") [typeNum, typeNum] typeNum
(Compound ["salesA", "salesB"]
(eCall "bonus1" [eCall "grossProfit" [eSymbol "salesA",
eSymbol "salesB"]]))
foo :: Function
foo = Function (Just "foo") [typeNum, typeNum] typeNum
(Compound ["a", "b"]
(eCall "+" [eCall "*" [eInt 2, eSymbol "a"],
eSymbol "b"])
)
eFoo :: Expr -> Expr -> Expr
eFoo e1 e2 = eCall "foo" [e1, e2]
max :: Function
max = let ex = eSymbol "x"
ey = eSymbol "y"
in Function (Just "max") [typeNum, typeNum] typeNum
(Compound ["x", "y"] (eIf (eGt ex ey) ex ey))
eMax :: Expr -> Expr -> Expr
eMax e1 e2 = eCall "max" [e1, e2]
fact :: Function
fact = let en = eSymbol "n" in
Function (Just "fact") [typeNum] typeNum
(Compound ["n"]
(eIf (eZerop en)
(eInt 1)
(eTimes en (eFact (eSub1 en)))))
eFact :: Expr -> Expr
eFact e1 = eCall "fact" [e1]
sumFromZero :: Function
sumFromZero = let en = eSymbol "n" in
Function (Just "sumFromZero") [typeNum] typeNum
(Compound ["n"]
(eIf (eZerop en)
(eInt 0)
(ePlus en (eSumFromZero (eSub1 en)))))
buggySumFromZero :: Function
buggySumFromZero =
let body = ePlus (eSym "n")
(eCall "buggySumFromZero"
[eMinus (eSym "n") (eInt 1)])
in Function (Just "buggySumFromZero") [typeNum] typeNum
(Compound ["n"] body)
eFib1 :: Expr -> Expr
eFib1 en = eCall "fib1" [en]
fib1 :: Function
fib1 = let en = eSymbol "n"
one = eInt 1
two = eInt 2
in Function (Just "fib1") [typeNum] typeNum
(Compound ["n"]
(eIf (eEq en one)
one
(eIf (eEq en two)
one
(ePlus (eFib1 (eMinus en two))
(eFib1 (eMinus en one))))))
eSumFromZero :: Expr -> Expr
eSumFromZero en = eCall "sumFromZero" [en]
rmul :: Function
rmul = let em = eSymbol "m"
en = eSymbol "n"
in Function (Just "rmul") [typeNum, typeNum] typeNum
(Compound ["m", "n"]
(eIf (eZerop en)
(eInt 0)
(ePlus em (eRmul em (eSub1 en)))))
eRmul :: Expr -> Expr -> Expr
eRmul em en = eCall "rmul" [em, en]
eGcd :: Expr -> Expr -> Expr
eGcd em en = eCall "gcd" [em, en]
gcd :: Function
gcd = let em = eSymbol "m"
en = eSymbol "n"
in Function (Just "gcd") [typeNum, typeNum] typeNum
(Compound ["m", "n"]
(eIf (eZerop (eMod em en))
en
(eGcd en (eMod em en))))
eEvenp, eOddp :: Expr -> Expr
eEvenp en = eCall "even?" [en]
eOddp en = eCall "odd?" [en]
evenp, oddp :: Function
evenp = let en = eSymbol "n"
in Function (Just "even?") [typeNum] typeBool
(Compound ["n"]
(eIf (eZerop en)
eTrue
(eOddp (eSub1 en))))
oddp = let en = eSymbol "n"
in Function (Just "odd?") [typeNum] typeBool
(Compound ["n"]
(eIf (eZerop en)
eFalse
(eEvenp (eSub1 en))))
eRabbitBabies, eRabbitAdults :: Expr -> Expr
eRabbitBabies en = eCall "rabbitBabies" [en]
eRabbitAdults en = eCall "rabbitAdults" [en]
rabbitTotal, rabbitAdults, rabbitBabies :: Function
rabbitTotal = let m = eSymbol "month"
in Function (Just "rabbitTotal") [typeNum] typeNum
(Compound ["month"]
(ePlus (eRabbitBabies m) (eRabbitAdults m)))
rabbitAdults = let m = eSymbol "month"
zero = eInt 0
one = eInt 1
in Function (Just "rabbitAdults") [typeNum] typeNum
(Compound ["month"]
(eIf (eEq m one)
zero
(ePlus
(eRabbitAdults (eSub1 m))
(eRabbitBabies (eSub1 m)))))
rabbitBabies = let m = eSymbol "month"
one = eInt 1
in Function (Just "rabbitBabies") [typeNum] typeNum
(Compound ["month"]
(eIf (eEq m one)
one
(eRabbitAdults (eSub1 m))))
buggyLength :: Function
buggyLength = let xs = eSymbol "xs"
one = eInt 1
in Function (Just "buggyLength")
[typeList (TypeVar "e1")] typeNum
(Compound ["xs"]
(eIf (eCall "null" [xs])
one
(ePlus one
(eCall "buggyLength"
[eCall "tail" [xs]]))))
listLength :: Function
listLength = let xs = eSymbol "xs"
one = eInt 1
zero = eInt 0
in Function (Just "length")
[typeList (TypeVar "e1")] typeNum
(Compound ["xs"]
(eIf (eCall "null" [xs])
zero
(ePlus one
(eCall "length"
[eCall "tail" [xs]]))))
listSum :: Function
listSum =
Function (Just "sum") [typeList typeNum] typeNum
(Compound ["xs"] sumbody)
sumbody :: Expr
sumbody =
eIf (eCall "null" [eSym "xs"])
(eInt 0)
(ePlus (eCall "head" [eSym "xs"])
(eCall "sum" [eCall "tail" [eSym "xs"]]))
buggySum :: Function
buggySum = let xs = eSymbol "xs"
in Function (Just "buggySum")
[typeList typeNum] typeNum
(Compound ["xs"]
(ePlus (eCall "head" [xs])
(eCall "buggySum" [eCall "tail" [xs]])))
exampleFunctions :: [Function]
exampleFunctions = [grossProfit, bonus1, bonus2
, foo, Language.Sifflet.Examples.max
, fact, sumFromZero, rmul, fib1
, Language.Sifflet.Examples.gcd, evenp, oddp
, rabbitBabies, rabbitAdults, rabbitTotal
, buggyLength, listLength, listSum, buggySum
, buggySumFromZero]
exampleFunctionNames :: [String]
exampleFunctionNames = map functionName exampleFunctions
exampleEnv :: Env
exampleEnv =
envInsertL baseEnv exampleFunctionNames (map VFun exampleFunctions)
getExampleFunction :: String -> Function
getExampleFunction = envGetFunction exampleEnv