-- higher.hs: conjuring higher order functions
--
-- Copyright (C) 2024-2025 Rudy Matela
-- Distributed under the 3-Clause BSD licence (see the file LICENSE).
import Conjure
appSpec :: ((Int -> Int) -> Int -> Int) -> [Property]
appSpec ($) =
[ property (((+1) $ 2) == 3)
, property ((abs $ (-2)) == 2)
, property ((negate $ 1) == -1)
]
composeSpec :: ((Int->Int) -> (Int->Int) -> Int->Int) -> [Property]
composeSpec (.) =
[ property $ ((*2) . (*3)) 1 == 6
, property $ (abs . negate) 7 == 7
, property $ (negate . abs) 8 == -8
]
flipSpec :: ((Int -> Int -> Int) -> Int -> Int -> Int) -> [Property]
flipSpec flip =
[ property $ flip const 1 2 == 2
, property $ flip div 2 10 == 5
, property $ flip mod 3 10 == 1
]
mapSpec :: ((Int -> Int) -> [Int] -> [Int]) -> [Property]
mapSpec map =
[ property $ map (*2) [1,2,3] == [2,4,6]
, property $ map abs [0,-1,-2] == [0,1,2]
]
foldSpec :: ((Int -> Int -> Int) -> Int -> [Int] -> Int) -> [Property]
foldSpec fold =
[ property $ fold (+) 0 [1,2,3] == 6
, property $ fold (*) 1 [1,2,3] == 6
, property $ fold (+) 0 [1,2,3,4] == 10
, property $ fold (*) 1 [1,2,3,4] == 24
]
filterSpec :: ((Int -> Bool) -> [Int] -> [Int]) -> [Property]
filterSpec filter =
[ property $ filter (<0) [0,1,-1,2,-2] == [-1,-2]
, property $ filter (>0) [0,1,-1,2,-2] == [1,2]
, property $ filter odd [0,1,2,3,4,5,6] == [1,3,5]
, property $ filter even [0,1,2,3,4,5,6] == [0,2,4,6]
]
main :: IO ()
main = do
conjureFromSpec "$" appSpec ingredients
conjureFromSpec "." composeSpec ingredients
conjureFromSpec "flip" flipSpec ingredients
conjureFromSpec "map" mapSpec ingredients
conjureFromSpec "fold" foldSpec ingredients
conjureFromSpec "filter" filterSpec ingredients
ingredients :: [Ingredient]
ingredients =
[ unfun ([] :: [Int])
, fun ":" ((:) :: Int -> [Int] -> [Int])
, guard
]