2014-11-04 46 views
3

我試圖寫簡單的函數,它接受一個列表的單元測試空列表,只是返回它,測試使用的測試代碼來測試它可以作爲一個函數,它

func :: [a] -> [a] 
func x = x 

預計給出一個空列表

emptyListTest :: Test 
emptyListTest = TestCase $ assertEqual "for (func [])," [] $ func [] 

main :: IO Counts 
main = runTestTT $ TestList [emptyListTest] 

但是,我得到的錯誤

No instance for (Show a0) arising from a use of `assertEqual' 
The type variable `a0' is ambiguous 
Possible fix: add a type signature that fixes these type variable(s) 
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 28 others 
In the expression: assertEqual "for (func [])," [] 
In the second argument of `($)', namely 
    `assertEqual "for (func [])," [] $ func []' 
In the expression: 
    TestCase $ assertEqual "for (func [])," [] $ func [] 

其他測試與非空力時sts工作正常,並且在ghci中調用func []進行手動測試時,該功能正常工作。

我也注意到,如果我創建了一個虛擬類型,並將該類型的元素作爲一個列表(如果這是說出它的正確方式),然後將其傳遞給測試似乎工作,並且測試通過

data Dummy = Dummy 
    deriving(Eq, Show) 

emptyList :: [Dummy] 
emptyList = [] 

emptyListTest :: Test 
emptyListTest = TestCase $ assertEqual "for (func [])," [] $ func emptyList 

這是爲什麼?有沒有辦法用一個空列表測試函數,而不必沿着虛擬類型路線下去?

回答

4

那麼,錯誤告訴你到底什麼是錯的。閱讀。

The type variable `a0' is ambiguous 

因此,輸入您的變量! GHC不可能知道用什麼類型來測試,除非你這樣做。

emptyListTest = TestCase $ assertEqual "for (func [])," [] $ func ([] :: [Int]) 

您可能必須啓用擴展才能進行內聯。

+0

那麼,爲什麼沒有翻譯錯誤的函數工作時,我只是把它傳遞'[]'沒有一個類型? – 2014-11-04 21:38:58

+1

@Michal Charemza GHCI有特殊的推理規則。 – alternative 2014-11-04 21:40:10

+2

爲了更確切地說,ghci默認''('Eq a,Show a)'約束,由'assertEqual'約束到'()',這是Haskell默認規則的擴展。請參閱[這裏](https://www.haskell.org/ghc/docs/latest/html/users_guide/interactive-evaluation.html#extended-default-rules)瞭解更多詳情! – yatima2975 2014-11-04 22:31:59

1

您需要爲空列表提供一個類型 - 否則GHC不知道您使用的是哪種列表。

一個可能的解決辦法:

.... assertEqual "for (func [])," [] $ func ([] :: [Int]) 
相關問題