Мне удалось продублировать ваше сообщение об ошибке в следующей программе. Обратите внимание, что подпись для foo
закомментирована:
import Test.QuickCheck
import Text.Show.Functions
-- foo :: [a] -> (a -> b) -> [b]
foo [] f = []
foo (x:xs) f = foo xs f
prop_1 :: [Int] -> Bool
prop_1 xs = foo xs id == xs
prop_2 :: [Int] -> (Int -> Int) -> (Int -> Int) -> Bool
prop_2 xs f g = foo (foo xs f) g == foo xs (g . f)
main = do
quickCheck prop_1
quickCheck prop_2
Если я верну подпись foo
, она будет хорошо проверена. Тесты, конечно же, проваливаются, поскольку foo
не делает то, что вы намереваетесь делать.
Проблема в том, что версия foo
, имеющаяся у вас здесь, имеет предполагаемую подпись:
foo :: [a] -> b -> [c]
поэтому в prop_2
нельзя определить тип элементов списка для самых верхних вызовов foo
, чтобы разрешить правильную операцию (==)
.
Если вы замените foo
на правильную версию:
foo :: [a] -> (a -> b) -> [b]
foo [] f = []
foo (x:xs) f = f x : foo xs f
затем тесты проходят и , вы можете снова закомментировать подпись, потому что правильный тип может быть выведен.