-- spec.hs: conjuring a function from a specification
--
-- Adapted from Colin Runciman's example "ListFuns"
import Conjure
import Test.LeanCheck (holds, exists)
import Prelude hiding (sum)
squareSpec :: (Int -> Int) -> [Property]
squareSpec square =
[ property $ square 0 == 0
, property $ square 1 == 1
, property $ square 2 == 4
]
squareIngredients :: [Ingredient]
squareIngredients =
[ unfun (0::Int)
, unfun (1::Int)
, fun "+" ((+) :: Int -> Int -> Int)
, fun "*" ((*) :: Int -> Int -> Int)
]
squarePropertySpec :: (Int -> Int) -> [Property]
squarePropertySpec square =
[ property $ \x -> square x >= x
, property $ \x -> square x >= 0
, property $ square 2 == 4
]
sumSpec :: ([Int] -> Int) -> [Property]
sumSpec sum =
[ property $ sum [] == 0
, property $ sum [1,2] == 3
, property $ sum [3,4,5] == 12
]
sumIngredients :: [Ingredient]
sumIngredients =
[ fun "null" (null :: [Int] -> Bool)
, unfun (0::Int)
, fun "+" ((+) :: Int -> Int -> Int)
, fun "head" (head :: [Int] -> Int)
, fun "tail" (tail :: [Int] -> [Int])
]
appSpec :: ([Int] -> [Int] -> [Int]) -> [Property]
appSpec (++) =
[ property $ [] ++ [0,1] == [0,1]
, property $ [2,3] ++ [] == [2,3]
, property $ [4,5,6] ++ [7,8,9] == [4,5,6,7,8,9]
]
appIngredients :: [Ingredient]
appIngredients =
[ fun "null" (null :: [Int] -> Bool)
, fun ":" ((:) :: Int -> [Int] -> [Int])
, fun "head" (head :: [Int] -> Int)
, fun "tail" (tail :: [Int] -> [Int])
]
main :: IO ()
main = do
conjureFromSpec "square" squareSpec squareIngredients
conjureFromSpec "square" squarePropertySpec squareIngredients
conjureFromSpec "sum" sumSpec sumIngredients
conjureFromSpec "++" appSpec appIngredients