Я пытаюсь написать свойство QuickCheck, которое принимает одну или несколько функций в качестве входных данных. Чтобы все было просто, рассмотрите свойство, чтобы проверить, что состав композиции эквивалентен последовательному функциональному приложению и быстрому и грязному тестовому драйверу:
import Test.QuickCheck
prop_composition :: (Int -> Int) -> (Int -> Int) -> Int -> Bool
prop_composition f g x = (f . g) x == f (g x)
main :: IO ()
main = quickCheck prop_composition
К сожалению, это не скомпилируется, потому что входные данные для свойства должны реализовать Show
, чтобы QuickCheck мог сообщить, какие входы вызвали сбой, но нет функции Show
для функций:
Test.hs:10:7:
No instance for (Show (Int -> Int))
arising from a use of `quickCheck' at Test.hs:10:7-33
Possible fix: add an instance declaration for (Show (Int -> Int))
In the expression: quickCheck prop_composition
In the definition of `main': main = quickCheck prop_composition
Я пробовал написать собственный экземпляр Show
для своих функций do-nothing для функций...
instance Show (a -> b) where
show _ = "[func]"
... который компилирует, но вызывает предупреждение с помощью -Wall
...
Test.hs:3:9: Warning: orphan instance: instance Show (a -> b)
..., что заставляет меня думать, что есть более правильный способ сделать это.
Моя кишка говорит мне, что ответ лежит в модуле Test.QuickCheck.Function
, но он не документирован, и я не могу понять, на типах подписи, что-нибудь в нем есть или как оно предназначено для использования.