2014-07-09 43 views
1

我是haskell的新手,我試圖解決這個haskell問題http://www.haskell.org/haskellwiki/99_questions/1_to_10#Problem_7。爲了驗證結果,我使用Test.QuickCheck模塊創建了一些測試。由於使用'=='而沒有出現(Eq a0)的實例

import Test.QuickCheck 
    import Test.QuickCheck.All 

    {- ------------- -} 
    {- SOLUTION  -} 
    {- ------------- -} 

    data NestedList a = Elem a | List [NestedList a] 

    flatten :: NestedList a -> [a] 
    flatten (Elem x) = [x] 
    flatten (List x) = concatMap flatten x 

    {- ------------- -} 
    {- TEST CASE  -} 
    {- ------------- -} 

    main = do 
     quickCheck (flatten (Elem 5) == [5]) 
     quickCheck (flatten (List [Elem 1, List [Elem 2, List [Elem 3, Elem 4], Elem 5]]) == [1,2,3,4,5]) 
     quickCheck (flatten (List []) == []) 

flatten實施是正確的,但,當我嘗試與quickCheck功能運行這段代碼我有一個錯誤。

Problem7.hs:43:39: 
     No instance for (Eq a0) arising from a use of ‘==’ 
     The type variable ‘a0’ is ambiguous 
     Note: there are several potential instances: 
      instance Eq a => Eq (GHC.Real.Ratio a) -- Defined in ‘GHC.Real’ 
      instance Eq() -- Defined in ‘GHC.Classes’ 
      instance (Eq a, Eq b) => Eq (a, b) -- Defined in ‘GHC.Classes’ 
      ...plus 114 others 
     In the first argument of ‘quickCheck’, namely 
      ‘(flatten (List []) == [])’ 
     In a stmt of a 'do' block: quickCheck (flatten (List []) == []) 
     In the expression: 
      do { quickCheck (flatten (Elem 5) == [5]); 
       quickCheck (flatten (List [Elem 1, List [...]]) == [1, 2, ....]); 
       quickCheck (flatten (List []) == []) } 

我知道,我需要的Eq一個實例來執行與(==)功能的比較,但我不知道如何實現它。有人能幫我嗎?

回答

3

問題是與陳述

quickCheck (flatten (List []) == []) 

,它是因爲你有List [],其類型爲NestedList a,但你希望它是Eq a => NestedList a。即使沒有任何值,當您使用==運算符時,它會強制該類型屬於Eq類型類別。有兩個簡單的修補程序解決此問題:

,而不是針對空列表進行比較列表,使用null,它具有執行

null :: [a] -> Bool 
null [] = True 
null _ = False 

這是我(和hlint工具)建議做。或者,你可以爲它提供一個明確的類型簽名:

quickCheck (flatten (List [] :: NestedList()) == []) 

在這裏,我用()的類型參數NestedList,因爲它的實施相當於

data() =() 

instance Eq() where 
    () ==() = True 

,所以你不能真的出問題了。

+0

我完全理解。非常感謝您的幫助! – Diullei

+0

@Diullei很高興能幫到你!僅供參考,取決於您使用的編輯器,可能會有一個'hlint'插件(我知道emacs有可能用於vim,我使用的是用於Sublime Text的),這對於發現這些類型的錯誤非常有用。如果你的編輯器沒有插件,你可以安裝'hlint'並從命令行使用它來給你這樣的建議。由於存在這個確切的錯誤,我已經使用該工具多次保存,因爲我總是忘記'null someList'和'someList == []'之間存在差異。 – bheklilr

+0

我最近開始學習Haskell,我正在尋找一個好的編輯器或IDE來使用。在這一刻,我使用沒有插件的崇高,我使用'runhaskell'命令行來測試。我會嘗試根據你的經驗使用一些崇高的插件;)。非常感謝! – Diullei

相關問題