Я пытаюсь проверить свою реализацию zipWith
с помощью QuickCheck. Моя реализация, myZipWith
, я хотел бы протестировать QuickCheck, сравнив ее со стандартной функцией. Что-то типа:
main = do
quickCheck (prop_myZipWith :: (Int -> Int -> Int) -> [Int] -> [Int] -> Bool)
prop_myZipWith :: (a -> b -> c) -> [a] -> [b] -> Bool
prop_myZipWith f x y = (myZipWith x y) == (zipWith f x y)
Это не работает, потому что (Int -> Int -> Int)
не является экземпляром Arbitrary
.
С помощью функций с одним аргументом это можно обойти, используя Test.QuickCheck.Function
Fun
(который создает экземпляр Arbitrary
). Например:
main = do
quickCheck (prop_myMap :: Fun Int Int -> [Int] -> Bool)
prop_myMap :: Fun a b -> [a] -> Bool
prop_myMap (Fun _ f) l = (myMap f l) == (map f l)
Я пытаюсь сделать что-то подобное, за исключением создания произвольных функций с двумя-аргументами.
Как создать произвольные экземпляры функций с двумя аргументами для тестирования QuickCheck функций высшего порядка, таких как zipWith
?
Fun Int (Fun Int Int)
? Помните, что не существует такой вещи, как бинарная функция, поскольку все содержит каррирование. - person chi   schedule 02.09.2017Show
. Но, как говорит @chi, каррирование решает вашу проблему тривиальным способом (а также лишь немного менее тривиальным способом, который также будет работатьFun (Int, Int) Int
). Вы можете найти определенияunFun (Fun _ f) = f; unFun2 f = unFun . unFun f
полезными. - person user2407038   schedule 02.09.2017Fun (a,b,...) x
менее болезненно работать, чемFun a (Fun b (... x ...))
- person dfeuer   schedule 22.09.2017