У меня есть функция rev
, которая возвращает некоторое значение для типа, принадлежащего к трем классам типов:
rev :: (Integral a, Show a, Read a) => a -> a
rev = read . reverse . show
Я хотел бы проверить некоторые свойства об этом с помощью quickcheck. Хотя я не заинтересован в тестировании отрицательных значений интегральных типов, потому что я использую Integer
из-за отсутствия типа Natural
в базовой библиотеке. Итак, я подумал, давайте возьмем значение, противоположное значению, сгенерированному, когда сгенерированное значение отрицательное, и я буду в порядке:
prop_id :: (Integral a, Show a, Read a) => Positive a -> Bool
prop_id n | n >= 0 = (rev.rev) n == n
| otherwise = let n' = -n in (rev.rev) n' == n'
(протестированное свойство здесь не важно - в частности, оно не подходит для очень простых значений, и я знаю об этом, это не является предметом этого вопроса)
Затем я наткнулся на модификатор Positive
и подумал, что, хотя мой тест теперь работает, было бы неплохо реализовать его более удобным способом. Итак, я попробовал:
prop_id :: (Integral a, Show a, Read a) => Positive a -> Bool
prop_id n = (rev.rev) n == n
Должен признаться, я был удивлен, когда он скомпилировался. Но потом при запуске теста выскочила ошибка:
*** Failed! Exception: 'Prelude.read: no parse' (after 1 test):
Positive {getPositive = 1}
Итак, я подумал: «Ммм, надо объявить эту Positive
штуку экземпляром Read
». Я так и сделал, но экземпляр уже объявлен в библиотеке quickCheck, кажется, потому что ghci кричал на меня.
И тут я заблудился, потому что не нашел хорошей документации (если она есть).
Мы будем благодарны за любой указатель, помогающий мне понять модификаторы и другие приятные вещи в библиотеке quickcheck.
rev (Positive {getPositive = 1})
этоread "}1 = evitisoPteg{ evitisoP"
. - person Daniel Wagner   schedule 18.09.2012