2016-06-10 113 views
0
  1. 我必須重載函數排序。函數的參數是一個數字,它們必須按參數0的值排序。這是我的嘗試:Haskell函數重載

    Prelude>instance (Num a, Ord b) => Ord (a -> b) where f > g = f 0 > g 0 
    

    ,但它產生的錯誤

    Could not deduce (Eq (a -> b)) 
    arising from the superclasses of an instance declaration 
    from the context (Num a, Ord b) 
    bound by the instance declaration at <interactive>:117:10-39 
    In the instance declaration for `Ord (a -> b)' 
    
  2. 我也想實例化奧德類名單。列表排序將通過每個列表的第一個元素之間的比較給出。例如[1,2] < [2,3]因爲1 < 2.

    instance Ord a => Ord [a] where 
        (h1:_) <= (h2:_) = h1 <= h2 
    

    這也產生下一個錯誤:

    Ambiguous occurrence `<=' 
    It could refer to either `Main.<=', 
            defined at C:\Users\user-name\Desktop\test.hs:2:8 
            or `Prelude.<=', 
            imported from `Prelude' at C:\Users\user-name\Desktop\test.hs:1:1 
            (and originally defined in `GHC.Classes') 
    

我想可能還沒有非常理解以及Haskell中的函數重載。也許有人可以解釋我做錯了什麼。

+3

您是否定義了自己的<='?Prelude已經有一個'<=',所以你應該選擇你想要的那個(這就是第二個錯誤信息所說的)。第一個錯誤是說沒有爲函數之間的平等定義內置。另外,Haskell沒有函數重載。 – pdexter

+0

因爲那麼'[1,1] <= [1,2]'和'[1,2] <= [1,1]'但當然是'[1,1]/= [1,2]' - 你也無法比較空列表...你爲什麼要這樣做? – Carsten

+0

這個練習的目的是理解不做「有意義」的事情的原則。 – zaig

回答

3
  1. 不要這樣做。您正在定義孤立實例(這些實例既不在data的模塊中,也不在class中);這種情況下「隱藏」在進口,這通常是一個更大的項目維護的痛苦。 (有時你不會避開孤立的實例,特別是當從不相關的包中合併數據和類時;但函數,列表和Ord都在基本庫中,如果在那裏沒有定義實例,那麼可以確定有一個很好的理由

  2. 如果你定義一個類的實例,看看類定義Ord被這樣定義:!

    class (Eq a) => Ord a where 
        ... 
    

    這意味着,中Ord任何實例必須是Eq實例太。這也是編譯器告訴你的。所以,如果你定義了這個實例,你還需要添加

    instance (Num a, Eq b) => Eq (a -> b) where f==g = f 0 == g 0 
    

    這是唯一一個與您的Ord兼容的實例。坦率地說,這只是錯誤的,因爲大多數被認爲是平等的功能是而不是等於!

  3. Haskell確實不是根本就沒有重載。如果您在模塊Main中定義了功能<=,則這是與標準<=又名Prelude.<=完全不相關的功能。您可以定義這樣一個新功能,但要使用它,您需要消除歧義。下面應該工作:

    instance Ord a => Ord [a] where 
        (h1:_) <= (h2:_) = h1 Main.<= h2 
    

    雖然再次,這不是一個好主意–你根本不應該擺在首位定義Main.<=,而是把它的定義就在Ord實例。

+1

'Ord [a]'實例不會與'Prelude'實例重疊嗎? – chi

+0

我現在明白你在說什麼了。我還有一個問題。爲什麼這個工作'實例(顯示b,數字a)=>顯示(a - > b)其中顯示f =顯示(f 0)',我不必做'實例(顯示b,數字a)= > Show(a - > b)where f = Main.show(f 0)'? – zaig

+0

因爲與'<='不同,你顯然試圖自己定義一個新的'',你從來沒有定義過自己的'show'函數。因此很明顯'show'指的是'Prelude.show',而'Main.show'根本不存在。 – leftaroundabout