QuickCheck で答え合わせ

プログラミングHaskell の練習問題で QuickCheck を使うのに、ちょうどよさそうな問題があったので試してみた。
問題は、map と filter を使って [f x | x <- xs, p x] を書き直せ、というもの。以下、できたコード。

filteredMap :: (a -> b) -> (a -> Bool) -> [a] -> [b]
filteredMap f p = map f . filter p

先日 QuickCheck を知ったところなので、早速答え合わせに使ってみようとした。

import Test.QuickCheck

filteredMap :: (a -> b) -> (a -> Bool) -> [a] -> [b]
filteredMap f p = map f . filter p

prop_model0 :: (Int -> Int) -> (Int -> Bool)  -> [Int] -> Bool
prop_model0 f p xs = [f x | x <- xs, p x] == filteredMap f p xs

そしたら、こんなエラーが

<interactive>:1:0:
    No instances for (Show (Int -> Int), Show (Int -> Bool))
      arising from a use of `quickCheck' at <interactive>:1:0-21
    Possible fix:
      add an instance declaration for
      (Show (Int -> Int), Show (Int -> Bool))
    In the expression: quickCheck prop_model0
    In the definition of `it': it = quickCheck prop_model0

Show の インスタンスじゃないとダメらしい。なので、map と filter に渡す関数は、内部で定義するようにしたらうまくいった。問題を解くよりも、このエラーを解決する方が時間を要した。

prop_model0 xs = [f x | x <- xs, p x] == filteredMap p f xs
  where f = (*2)
        p = odd
GHCi> quickCheck prop_model0 
+++ OK, passed 100 tests.

実行する関数をいろいろ試したい場合はどうすれば、効率よくできるのだろうか。まあ、関数がなんであれ結果は同じになるだろうから、一つ試せばいいのだけれど。