2016-06-10 112 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