Как использовать quickcheck в основном - PullRequest
3 голосов
/ 22 августа 2011

Я пишу тест для функции бинарного поиска, которую я написал.

module Tests where

import Data.List (sort)
import Test.QuickCheck
import BinarySearch (binarySearch)

prop_equals_elem x xs = (binarySearch x $ sort xs) == (x `elem` xs)

args = Args {replay = Nothing, maxSuccess = 200, maxDiscard=200, maxSize=200, chatty = False}

main = do
    quickCheck (prop_equals_elem :: (Ord a) => a -> [a] -> Bool)

Хорошо работает с использованием quickCheck в ghci, но когда я пытаюсь запустить main, выдает ошибку

Tests.hs:12:5:
    Ambiguous type variable `a0' in the constraints:
      (Arbitrary a0) arising from a use of `quickCheckWith'
          at Tests.hs:12:5-18
      (Show a0) arising from a use of `quickCheckWith'
          at Tests.hs:12:5-18
      (Ord a0) arising from an expression type signature
          at Tests.hs:12:26-72

Почему это не работает в основном, но работает в ghci?

Ответы [ 2 ]

4 голосов
/ 22 августа 2011

Это, вероятно, вызвано расширенными правилами по умолчанию в GHCi .

При тестировании подобной функции вам необходимо использовать конкретный тип элемента.GHCi по умолчанию выберет тип элемента () из-за расширенных правил, но этого не произойдет при обычной компиляции кода, поэтому GHC сообщает, что не может определить, какой тип элемента использовать.

ВыНапример, вместо теста можно использовать Int.() довольно бесполезен для тестирования этой функции, так как все элементы будут одинаковыми.

quickCheck (prop_equals_elem :: Int -> [Int] -> Bool)

Если он работает для Int, он должен работать для любого типа из-за параметричности.

3 голосов
/ 22 августа 2011

Когда вы запускаете тест QuickCheck, QuickCheck должен знать, как генерировать данные.Здесь вы сказали только то, что ваш код должен работать с произвольным типом класса Ord, которого недостаточно для начала тестирования.Отсюда ошибка с классами неоднозначных типов.

Если вам просто нужен произвольный экземпляр Ord, как показано здесь, тогда что-то вроде Int будет хорошим выбором для вашего тестирования.Это простой тип с линейным порядком.Поэтому попробуйте установить тип Int в main, например:

quickCheck (prop_equals_elem :: Int -> [Int] -> Bool)

Что касается того, почему он работает в GHCi, ответ по умолчанию.По умолчанию GHCi по умолчанию использует переменные типа (), чтобы избежать ложных ошибок в ситуациях, когда вы действительно не заботитесь о значении.На самом деле это ужасный выбор: вы не протестируете ничего интересного, просто протестировав тип ()!Опять же, явная сигнатура типа лучше.

...