2012-04-27 2 views
0

Network.HTTP에서 ResponseCode를 사용하는 함수가 있습니다. QuickCheck로 테스트하기 위해 ResponseCode에 임의의 인스턴스를 작성하려고했습니다. (당신이 모를 경우에, ResponseCode는 그 라이브러리에있는 int의 3 배에 불과하다 : type ResponseCode = (Int, Int, Int)).임의의 인스턴스를 사용하여 트리플 (Network.HTTP.ResponseCode)을 생성하십시오.

그래서 나는 이런 식으로 뭔가 썼다 : 모든

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

먼저, GHC 정말하지 않은 (내가 유형을 사용하고 방법은 표준 하스켈은 그래서 몇 가지 컴파일러 플래그를 사용하는 것 아니라고 불평 깃발이없는이 간단한 문제에 대한 쉬운 해결책이 있어야만한다고 생각하기 때문에 원하는 것).

두 번째로, 내 임의 함수의 유형이 잘못되어 매우 분명합니다. 그러나 실제로 1-6 범위의 임의의 Ints를 가진 트리플을 반환하는 함수를 작성하는 방법을 알지 못했습니다.

여기 누군가 나를 도울 수 있다면 고맙겠습니다.

감사합니다. 이것은 (INT는, INT, 지능)이 이미 임의의 인스턴스임을 의미

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

: 모든

답변

5

우선, 이미 두 인스턴스가된다. 이것은 타입 동의어 ResponseCode가 이미 인스턴스임을 의미합니다. 두 번째 인스턴스는 정의하고 사용할 수 없습니다.

당신은 Test.QuickCheck.Gen.such를 사용해 볼 수 있습니다. 그러나 나는이 경우 잘 작동하지 않을 것이라고 가정합니다. , 나는 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) 

아니면 내장 (int, int, int)를 인스턴스와 사후 처리를 (SUCC (mod 6).)와 세 가지 요소를 사용합니다.

+0

좋은 답변입니다. 만약 당신이 새로운 타입을 만들려고한다면'ResponseCode'는 6 개의 값만 가질 수 있기 때문에'data와 같은 것을 정의 할 수도 있습니다. ResponseCode = Success | 부분 | 실패 | FileNotFound | NotAuthorized | I'mittleTeapot' 또는 그런 것. –

관련 문제