2011-08-22 3 views
3

나는 이진 검색 기능에 대한 테스트를 작성했습니다.메인에서 quickcheck을 사용하는 방법

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에서합니까?

+0

http://hackage.haskell.org/package/test-framework – alternative

답변

4

이것은 extended defaulting rules in GHCi이 원인 일 수 있습니다.

이와 같은 기능을 테스트 할 때는 구체적인 요소 유형을 사용해야합니다. GHCi는 확장 된 규칙 때문에 요소 유형을 ()으로 기본 설정하지만 코드를 정상적으로 컴파일 할 때 발생하지 않으므로 GHC는 사용할 요소 유형을 파악할 수 없다고 말합니다.

대신 예를 들어 Int을 테스트 용으로 사용할 수 있습니다. ()은 모든 요소가 동일하기 때문에이 함수를 테스트하는 데 꽤 쓸모가 없습니다.

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

Int에서 작동하는 경우 파라 메트릭 때문에 모든 유형에서 작동합니다.

3

빠른 검사를 실행할 때 빠른 검사는 데이터를 생성하는 방법을 알아야합니다. 여기서는 코드가 임의 유형의 Ord 유형 클래스에서 작동해야한다고 말 했으므로 테스트를 시작하기에 충분하지 않습니다. 따라서 모호한 유형 클래스에 대한 오류.

여기에 표시된대로 임의의 Ord 인스턴스 만 필요하면 Int과 같은 것이 테스트를위한 좋은 선택입니다. 선형 순서가있는 단순 유형입니다. 그래서 같이 mainInt에 유형을 고정하십시오 :

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

가 GHCi에서 작동하는 이유에 관해서는, 대답은 디폴트입니다. GHCi는 가능할 때마다 유형 변수를 기본값으로 ()으로 기본 설정합니다. 실제로 값을 신경 쓰지 않는 상황에서 허위 오류를 피하기 위해서입니다. 실제로 그것은 끔찍한 선택입니다 : () 유형으로 테스트하여 흥미로운 것을 테스트하지 않겠습니다! 다시 말하지만, 명시 적 형식 서명이 더 좋습니다.

+1

QuickCheck는 주어진 유형에서 임의의 요소를 선택할 수는 있지만 typeclass를 인스턴스화하는 임의의 유형을 선택할 수는 없습니다. 그래도 흥미로운 향상이 될 것입니다. –

관련 문제