0

Network.HTTP から ResponseCode を受け取る関数があります。QuickCheck でテストするために、ResponseCode の Arbitrary のインスタンスを書きたいと思いました。(ご存じない場合は、ResponseCode は、そのライブラリ内の int のトリプルにすぎません: type ResponseCode = (Int, Int, Int))。

だから私はこのようなものを書きました:

instance Arbitrary ResponseCode where
    arbitrary = triple ( elements [1..6] )
       where triple f = (f, f, f)

まず第一に、GHC は、私が型を使用している方法が標準的な Haskell ではないので、いくつかのコンパイラ フラグを使用する必要があると文句を言っています (これは、この単純な問題に対して、フラグ)。

次に、任意の関数の型が間違っています。これは明らかです。しかし、その後、1 から 6 の範囲のランダムな Int を持つトリプルを返す関数の書き方が本当にわかりませんでした。

誰かがここで私を助けてくれれば幸いです。

ありがとうございました。

4

1 に答える 1

5

まず、すでに次の 2 つのインスタンスがあります。

instance Arbitrary Int
instance (Arbitrary a, Arbitrary b, Arbitrary c) =>
         Arbitrary (a, b, c)

これは、(Int,Int,Int) が既に Arbitrary のインスタンスであることを意味します。これは、型シノニム ResponseCode がすでにインスタンスであることを意味します。2 番目のインスタンスを定義して使用することはできません。

Test.QuickCheck.Gen. suchThat を使用してみることができますが、この場合はうまく機能しないと仮定しています。可能であれば、newtype ラッパーを使用することをお勧めします。

import Test.QuickCheck
import Network.HTTP.Base
import Control.Applicative
import System.Random

newtype Arb'ResponseCode = Arb'ResponseCode { arb'ResponseCode :: ResponseCode }
  deriving (Show)

instance Arbitrary Arb'ResponseCode where
  arbitrary = do
      responseCode <- (,,) <$> f <*> f <*> f
      return (Arb'ResponseCode responseCode)
    where f = elements [1..6]

-- To use this you can call
-- (fmap arb'ResponseCode arbitrary)
-- instead of just (arbitrary)

modまたは、組み込みの (Int,Int,Int) インスタンスを使用して、3 つの要素を (succ . ( 6))で後処理することもできます。

于 2012-04-27T06:42:50.640 に答える