Hspec & QuickCheck - неоднозначная переменная типа a0? - PullRequest
0 голосов
/ 14 октября 2018

Я написал в Haskell функцию, которая принимает список произвольных элементов и возвращает (сопоставленный) список кортежей.Каждый кортеж содержит исходный элемент и дробь, причем все дроби в списке добавляются к 1 (поэтому я просто вычисляю дробь один раз, используя 1 ``div`` length xs, и применяю для нее все элементы).Это код:

uniform :: [a] -> [(a, Int)]
uniform xs = map (\x -> (x, prob)) xs
  where prob = 1 `div` (length xs)

(Отказ от ответственности: на самом деле это немного упрощенная версия, но я создаю точно такое же поведение, поэтому, надеюсь, этого достаточно).

Я пытаюсьпокрыть это тестом на основе свойств с использованием Hspec и Quickcheck:

spec = do
    describe "uniform" $ do

        it "produces a uniform distribution summing to 1" $ property $
            let totalProbability ((_, p):xs) = p + (totalProbability xs)
            in (\xs -> (totalProbability $ uniform xs) `shouldBe` 1)

Однако, когда я запускаю это, я получаю эту ошибку:

• Ambiguous type variable ‘a0’ arising from a use of ‘property’
  prevents the constraint ‘(Arbitrary a0)’ from being solved.
  Probable fix: use a type annotation to specify what ‘a0’ should be.
  These potential instances exist:
    instance (Arbitrary a, Arbitrary b) => Arbitrary (Either a b)
      -- Defined in ‘Test.QuickCheck.Arbitrary’
    instance Arbitrary Ordering
      -- Defined in ‘Test.QuickCheck.Arbitrary’
    instance Arbitrary Integer
      -- Defined in ‘Test.QuickCheck.Arbitrary’
    ...plus 19 others
    ...plus 62 instances involving out-of-scope types
    (use -fprint-potential-instances to see them all)
• In the second argument of ‘($)’, namely
    ‘property
       $ let totalProbability ((_, p) : xs) = p + (totalProbability xs)
         in (\ xs -> (totalProbability $ uniform xs) `shouldBe` 1)’
  In a stmt of a 'do' block:
    it "produces a uniform distribution summing to 1"
      $ property
          $ let totalProbability ((_, p) : xs) = p + (totalProbability xs)
            in (\ xs -> (totalProbability $ uniform xs) `shouldBe` 1)
  In the second argument of ‘($)’, namely
    ‘do it "produces a uniform distribution summing to 1"
          $ property
              $ let totalProbability ((_, p) : xs) = ...
                in (\ xs -> (totalProbability $ uniform xs) `shouldBe` 1)’

|12 |он "производит равномерное распределение, суммирующее 1" $ property $ |^^^^^^^^^^ ...

Я предполагаю, что где-то я не дал QuickCheck достаточно информации о том, как генерировать тестовое значение, но я не уверен, куда идти дальше.

Любая помощь будет принята с благодарностью.

Спасибо!

1 Ответ

0 голосов
/ 14 октября 2018

Вам необходимо указать тип для xs: это список строк?Интс?булевы?Это сделано для того, чтобы QuickCheck мог генерировать случайную выборку такого типа.

Вы можете написать, например:

...
in (\xs -> (totalProbability $ uniform (xs :: [Int])) `shouldBe` 1)
...