Почему этот тест QuickCheck с полиморфной подписью проходит, когда он должен провалиться?

Учитывая следующий тестовый код с использованием QuickCheck, я ожидаю, что prop_Max errMax должен потерпеть неудачу как определение errMax это неверно.

Это происходит, когда я использую данную подпись для prop_Max с конкретным типом Int, Однако, когда я даю ему более полиморфный закомментированный тип, используя OrdТест проходит. Почему это?

import Test.QuickCheck

myMax :: Ord a => a -> a -> a
myMax x y  
    |x > y = x
    |otherwise = y

errMax :: Ord a => a -> a -> a
errMax x y
    |x > y = y
    |otherwise = x


-- prop_Max :: Ord a => (a -> a -> a) -> a -> a -> Bool
prop_Max :: (Int -> Int -> Int) -> Int -> Int -> Bool
prop_Max maxFunc x y = (x <= maxFunc x y) && (y <= maxFunc x y)

-- in ghci
-- quickCheck (prop_Max max)
-- quickCheck (prop_Max myMax)
-- quickCheck (prop_Max errMax)

1 ответ

Проблема с дефолтом.

В ghci по умолчанию ExtendedDefaultRules расширение включено. Это означает, что с общим Ord тип подписи, a переменная типа по умолчанию равна () тип.

Поскольку единственное допустимое значение типа () это значение () ваш тест проходит даже для определения max это было бы неправильно на более сложном типе.

С тестами QuickCheck вы обычно должны четко указывать тип, на котором вы ожидаете выполнение теста. Так что здесь вы можете сохранить полиморфную подпись для prop_Max, но явно выберите Int когда ты звонишь quickCheck:

quickCheck (prop_Max (errMax :: Int -> Int -> Int))
Другие вопросы по тегам