4

私が書いた二分探索関数のテストを書いています。

module Tests where

import Data.List (sort)
import Test.QuickCheck
import BinarySearch (binarySearch)

prop_equals_elem x xs = (binarySearch x $ sort xs) == (x `elem` xs)

args = Args {replay = Nothing, maxSuccess = 200, maxDiscard=200, maxSize=200, chatty = False}

main = do
    quickCheck (prop_equals_elem :: (Ord a) => a -> [a] -> Bool)

ghciでquickCheckを使用するとうまく機能しますが、メインを実行しようとするとエラーが発生します

Tests.hs:12:5:
    Ambiguous type variable `a0' in the constraints:
      (Arbitrary a0) arising from a use of `quickCheckWith'
          at Tests.hs:12:5-18
      (Show a0) arising from a use of `quickCheckWith'
          at Tests.hs:12:5-18
      (Ord a0) arising from an expression type signature
          at Tests.hs:12:26-72

これがメインでは機能しないのに、ghci では機能するのはなぜですか?

4

2 に答える 2

5

これは、GHCiの拡張されたデフォルトルールが原因である可能性があります。

このような関数をテストするときは、具体的な要素タイプを使用する必要があります。GHCiは()、拡張ルールのために要素タイプをデフォルトで設定しますが、コードを通常どおりにコンパイルする場合はこれが発生しないため、GHCは、使用する要素タイプを特定できないことを通知します。

たとえば、Int代わりにテストに使用できます。()すべての要素が同じになるため、この関数のテストにはまったく役に立ちません。

quickCheck (prop_equals_elem :: Int -> [Int] -> Bool)

で機能する場合はInt、パラメトリシティにより、どのタイプでも機能するはずです。

于 2011-08-22T15:33:07.473 に答える
3

QuickCheck テストを実行する場合、QuickCheck はデータの生成方法を知る必要があります。ここでは、コードが型クラスの任意の型で動作する必要があることだけを伝えましたがOrd、これではテストを開始するには不十分です。したがって、あいまいな型クラスに関するエラー。

Ordここに表示されているように、任意のインスタンスだけが必要な場合は、次のようなものIntがテストに適しています。線形の順序を持​​つシンプルなタイプです。Int次のように、タイプをinに修正してみてくださいmain

quickCheck (prop_equals_elem :: Int -> [Int] -> Bool)

なぜ GHCi で動作するのかというと、答えはデフォルトです。GHCi は()可能な限りデフォルトで型変数を に設定します.これは, 値を本当に気にしない状況で偽のエラーが発生するのを避けるためです. 実際、それはひどい選択です: 型でテストするだけでは、興味深いものは何もテストできません()! 繰り返しますが、明示的な型シグネチャの方が優れています。

于 2011-08-22T15:37:02.473 に答える