#haskell #quickcheck
#haskell #быстрая проверка
Вопрос:
Я начинаю изучать Haskell, выполняя 99 задач Haskell. http://www.haskell.org/haskellwiki/H-99:_Ninety-Nine_Haskell_Problems Я бы хотел написать тесты для каждой программы / функции с помощью quickcheck.
У меня есть следующий код:
импорт теста.быстрая проверка импорт текста.Printf main = mapM_ ((s,a) -> printf "%-25s: " s >> a) тесты -- 1 myLast lst = последний lst prop_1a xs x = myLast (xs [x]) == (x::String) myLast' = head . обратный prop_1b xs x = myLast' (xs [x]) == (x::String) тесты = [("1a", QuickCheck prop_1a) ,("1b", QuickCheck prop_1b) ]
Я мог бы написать myLast''
, myLast'''
, и т.д. Есть ли способ протестировать все эти методы без необходимости дублирования кода и свойств быстрой проверки?
Связанный вопрос: прямо сейчас я говорю quickcheck использовать строки. Есть ли способ случайным образом использовать разные типы для тестирования?
Комментарии:
1. Пожалуйста, никогда не используйте слово «метод» как синоним «функции»
Ответ №1:
Просто используйте функцию для проверки в качестве другого аргумента:
prop_1 last xs x = last (xs [x]) == (x :: Int)
tests = zipWith mkTest ['a'..] [myLast, myLast']
where mkTest letter func = ('1':[letter], quickCheck $ prop_1 func)
Ответ №2:
Есть ли способ протестировать все эти методы без необходимости дублирования кода и свойств быстрой проверки?
Почему бы не написать prop так, чтобы он принимал список функций, а затем выполнял проверку каждой из них? Тогда вы бы запустили его как quickCheck (myProp [myLast, myLast', myLast''])
.
редактировать: я боялся, что вы можете спросить, что:P Чтобы сделать это, как я сказал выше, myProp
должен взять список функций, все из которых имеют тот же тип, last
что и , и возвращать логическое значение:
myProp :: [([a] -> a)] -> Bool
Но теперь, когда я смотрю на это, возможно, было бы лучше (и более аналогично вашему первоначальному подходу), чтобы он также принимал список и элемент, поэтому я думаю, что сделаю это вместо этого:
myProp :: [([a] -> a)] -> [a] -> a -> Bool
Если список пуст, мы возвращаем true:
myProp [] _ _ = True
Если нет, то мы проверяем, выполняется ли свойство для первой функции в списке, а затем рекурсивно проверяем остальную часть списка:
myProp [f:fs] xs x = f (xs [x]) == x amp;amp; myProp fs xs x
(Я не уверен, почему вы написали x::String
в своей реализации. Я не думаю, что вам это нужно — last
работает со списками чего угодно, а не только со списками строк. Но я на самом деле не проверял это, поэтому я предполагаю, что у вас была веская причина.)
В любом случае, я думаю, что это должно сработать, но я на самом деле не пробовал. Пожалуйста, не стесняйтесь редактировать и исправлять любые глупые синтаксические ошибки, которые я мог допустить, или что-то еще.
Комментарии:
1. У меня возникли проблемы с определением синтаксиса для этого — не могли бы вы изменить свой ответ, чтобы показать это?
2. Я добавил x::String, потому что мне нужно было где-то предоставить информацию о типе.