Я работаю над Real World Haskell, одним из упражнений главы 4 является реализация foldr
-ориентированного версия concat
. Я подумал, что это будет отличным кандидатом для тестирования с помощью QuickCheck, поскольку существует уже существующая реализация для проверки моих результатов. Однако это требует от меня определения экземпляра класса типов Arbitrary
, который может генерировать произвольные [[Int]]
. Пока не могу понять, как это сделать. Моя первая попытка была:
module FoldExcercises_Test
where
import Test.QuickCheck
import Test.QuickCheck.Batch
import FoldExcercises
prop_concat xs =
concat xs == fconcat xs
where types = xs ::[[Int]]
options = TestOptions { no_of_tests = 200
, length_of_tests = 1
, debug_tests = True }
allChecks = [
run (prop_concat)
]
main = do
runTests "simple" options allChecks
Это приводит к тому, что тесты не проводятся. Глядя на различные фрагменты, я догадался, что требуется объявление экземпляра Arbitrary
, и добавил
instance Arbitrary a => Arbitrary [[a]] where
arbitrary = sized arb'
where arb' n = vector n (arbitrary :: Gen a)
Это привело к тому, что ghci пожаловался, что объявление моего экземпляра недействительно и что добавление -XF flexibleInstances может решить мою проблему. Добавление директивы {-# OPTIONS_GHC -XFlexibleInstances #-}
приводит к несоответствию типов и предупреждению о перекрывающихся экземплярах.
Итак, мой вопрос: что нужно, чтобы это работало? Я, очевидно, новичок в Haskell и не нахожу никаких ресурсов, которые могли бы мне помочь. Любые указатели очень ценятся.
Редактировать
Похоже, что вывод QuickCheck ввел меня в заблуждение, когда при первом тестировании fconcat
определяется как
fconcat = undefined
Собственно правильная реализация функции действительно дает ожидаемый результат. DOOP!