2014-11-16 3 views
1

저는 haskell을 처음 사용하고 있으며 hspec을 동시에 배우려고합니다.'shouldBe'의 사용으로 인해 (Show a0) 인스턴스가 없습니다.

module ExercisesSpec where 

import Test.Hspec 
import Test.QuickCheck 
import Control.Exception (evaluate) 


halve :: [a] -> ([a], [a]) 
halve xs = splitAt (length xs `div` 2) xs 

main :: IO() 
main = hspec $ do 
    describe "halve" $ do 
    it "0 elements" $ do 
     halve [] `shouldBe` ([],[]) 

    it "1 element" $ do 
     halve [1] `shouldBe` ([],[1]) 

    it "2 elements" $ do 
     halve [1,2] `shouldBe` ([1],[2]) 

    it "3 elements" $ do 
     halve [1,2,3] `shouldBe` ([1],[2,3]) 

    it "4 elements" $ do 
     halve [1,2,3,4] `shouldBe` ([1,2],[3,4]) 

나머지 테스트는 통과하지만 0 개 요소에 대한 테스트는 실패합니다.

No instance for (Show a0) arising from a use of ‘shouldBe’ 
The type variable ‘a0’ is ambiguous 
Note: there are several potential instances: 
    instance Show Double -- Defined in ‘GHC.Float’ 
    instance Show Float -- Defined in ‘GHC.Float’ 
    instance (Integral a, Show a) => Show (GHC.Real.Ratio a) 
    -- Defined in ‘GHC.Real’ 
    ...plus 38 others 
In a stmt of a 'do' block: halve [] `shouldBe` ([], []) 
In the second argument of ‘($)’, namely 
    ‘do { halve [] `shouldBe` ([], []) }’ 
In a stmt of a 'do' block: 
    it "0 elements" $ do { halve [] `shouldBe` ([], []) } 

ghci에서 시도해도 정상적으로 작동합니다.

*Exercises> halve [] 
([],[]) 

나를 도와 줄 사람이 있습니까?

+2

GHCi는 다형성 값을 표시하기위한 다른 규칙과 함께'-XExtendedDefaultRules'를가집니다. 'let x :: Num a => a를 시도해보십시오. x = 1' 다음에'x'가옵니다. 그것은'Num'의 어떤 인스턴스를 사용할 지 알지 못하고'1'을 출력합니다. 여기서 문제는 컴파일 할 때 GHC가 사용할'Show '의 버전을 알지 못한다는 것입니다. halve [1]'shouldBe'와 같은 일을 할 수 있습니다. (([], []) : ([Int], [Int])) [], [1]) :: ([Int], [Int]))'''등등. 귀하의 코드는 GHC가 파악 하기엔 너무 다형 적입니다. – bheklilr

답변

5

아, 내 자신의 질문에 대답하기 위해 형식을 좀 더 구체적으로 지정해야합니다. 내 기능 위에 halve :: [Int] -> ([Int], [Int])을 추가하면 작동합니다.

나는 내 수업의 토론 방에 읽기 좋은 답변을 인용 :

pbl64k

일반적으로 목록에 대한 유도 더보기 인스턴스가 확실히 없습니다. 함수 목록은 어떻습니까? REPL은 Show 인스턴스가있는 구체적인 유형을 유추합니다. 그러나 일반적으로 자신이 하나가 아니라면 - 일반적으로 하나가 있다고 기대하지 마십시오.

treeowl

pbl64k는 권리의 종류 및 종류의 잘못된 것입니다. a에 대한 Show 인스턴스가있는 경우 [a]에 대한 Show 인스턴스가 있습니다. 자동으로 파생됩니다. 문제는 하스켈이 어떤 인스턴스인지 알지 못한다는 것입니다. []는 하나의 값처럼 보일 수 있습니다. (그리고 기계어 코드에서는 아마도 가능할 것입니다.)하지만 하스켈 수준에서는 다형성 생성자입니다. 모든 목록 유형을 사용할 수 있으므로 어떤 목록 유형을 사용할지 결정해야합니다.

+0

그냥 재미있게 : 목록이 비어 있어도 내용이 보이지 않아도 show 인스턴스가있는 목록 유형을 작성할 수 있습니다. 목록이 없으면 일반 목록처럼 표시 할 수 있습니다. 빈. 이를 위해서는 많은 언어 확장이 필요하지만 훨씬 엄격한 정적 제약 조건을 적용하기 때문에 작업하기가 다소 어렵습니다. – Cubic