Тест Monadic QuickCheck не работает для произвольного массива Repa

Я пытаюсь написать тесты для произвольных массивов Repa в Haskell. Почему-то следующий фрагмент:

import Test.QuickCheck
import Test.QuickCheck.Monadic
import Data.Array.Repa (Array, DIM2)

prop_id :: Array U DIM2 Double -> Property
prop_id array = monadicIO $ array `R.equalsP` array >>= assert

выдает это исключение:

*** Failed! (after 1 test): 
Exception:
Test.QuickCheck.resize: negative size
CallStack (from HasCallStack):
    error, called at ./Test/QuickCheck/Gen.hs:82:22 in QuickCheck-2.9.2-Jyj4gc4JxkEIgGFLAsGhs9:Test.QuickCheck.Gen
Exception thrown while printing test case:
Test.QuickCheck.resize: negative size
CallStack (from HasCallStack):
    error, called at ./Test/QuickCheck/Gen.hs:82:22 in QuickCheck-2.9.2-Jyj4gc4JxkEIgGFLAsGhs9:Test.QuickCheck.Gen

Я не знаю, как интерпретировать эту информацию. Спасибо за вашу помощь.


person ethanabrooks    schedule 29.04.2017    source источник


Ответы (1)


Это ошибка экземпляра repa Arbitrary. arbitrary вылетает при размере 0. Пока вы можете исправить генератор, используемый вашим ресурсом:

quickCheck $ forAll (scale (+1) arbitrary) prop_id
person Li-yao Xia    schedule 29.04.2017
comment
Спасибо за ответ! Я бы сам не догадался. Есть ли способ сделать это с помощью quickCheckAll, то есть: runTests = $quickCheckAll $ forAll (scale (+1) arbitrary)? - person ethanabrooks; 30.04.2017
comment
К сожалению нет. Не существует такого тонкого способа настройки генераторов, используемых QuickCheck. Чтобы не калечить все ваши генераторы, вы должны переопределить Arbitrary экземпляры repa. Их корневой модуль импортирует экземпляры Arbitrary, и этого трудно избежать, поскольку он экспортирует тип Array. Однако свойства являются мономорфными, поэтому вы можете воспользоваться тем фактом, что существующие экземпляры Arbitrary являются параметрическими, и реализовать Arbitrary (Array U sh Double), например, в своем тестовом модуле с помощью {-# OVERLAPPING #-}, исправляя общий экземпляр repa. - person Li-yao Xia; 30.04.2017
comment
Сделаю! Спасибо. - person ethanabrooks; 30.04.2017
comment
Во-первых, я должен сказать, что ваше первое предложение сработало. Однако следующий код этого не сделал (выдал ту же ошибку, что и раньше): instance {-# OVERLAPPING #-} T.Arbitrary (Array U DIM1 Double) where arbitrary = T.scale (+1) $ T.arbitrary >>= A.arbitraryUShaped - person ethanabrooks; 30.04.2017
comment
Ваше свойство выше использует DIM2, поэтому этот экземпляр не выбран. - person Li-yao Xia; 30.04.2017