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