2016-06-10 15 views
0
  1. Ich muss Funktionsordnung überladen. Das Argument der Funktion ist eine Zahl und sie müssen nach ihrem Wert für das Argument 0 geordnet werden. Das ist, was ich versucht:Haskell-Funktion überladen

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

    aber es erzeugt den Fehler

    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. ich auch die Ord Klasse für Listen instanziiert möchten. Die Reihenfolge der Listen wird durch den Vergleich zwischen dem ersten Element jeder Liste bestimmt. Zum Beispiel [1,2] < [2,3], weil 1 < 2.

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

    Dies erzeugt auch den nächsten Fehler:

    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') 
    

Ich glaube, ich kann nicht sehr verstanden haben gut die Funktion Überladung in Haskell. Vielleicht könnte mir jemand erklären, was ich falsch mache.

+3

Definieren Sie Ihr eigenes '<='?Prelude kommt bereits mit einem '<=', also sollten Sie wählen, welches Sie wollen (das ist, was die zweite Fehlermeldung sagt). Der erste Fehler besagt, dass es keine integrierte Definition für die Gleichheit zwischen Funktionen gibt. Außerdem hat Haskell kein Funktionsüberladen. – pdexter

+0

Ihre Reihenfolge für die Liste wird sehr seltsam sein, denn dann "[1,1] <= [1,2]' und '[1,2] <= [1,1]' aber natürlich "[1,1]/= [1,2] '- auch du kannst keine leeren Listen vergleichen ... warum würdest du das tun? – Carsten

+0

Der Zweck der Übung ist es, das Prinzip zu verstehen, etwas nicht zu tun, das "Sinn macht". – zaig

Antwort

3
  1. Tun Sie dies nicht. Sie definieren hier verwaiste Instanzen (Instanzen, die weder im Modul der data noch der class gehören, zu denen sie gehören); Solche Fälle sind “ unsichtbar ” in Importe, die im Allgemeinen ein Schmerz für größere Projektwartung ist. (Manchmal kommen Sie nicht an verwaisten Instanzen vorbei, insbesondere wenn Sie Daten und Klassen aus nicht zusammenhängenden Paketen kombinieren; aber Funktionen, Listen und Ord befinden sich alle in der Basisbibliothek. Wenn dort keine Instanz definiert ist, können Sie ziemlich sicher sein es gibt einen guten Grund

  2. Wenn Sie eine Klasseninstanz definieren tun, bei der Klassendefinition aussehen Ord so definiert:!

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

    das bedeutet auch jede Instanz von Ord muss eine Instanz von Eq sein Das sagt Ihnen auch der Compiler: Wenn Sie diese Instanz definieren, müssen Sie auch

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

    Dies ist die einzige Instanz, die mit Ihrer Ord kompatibel ist. Ehrlich gesagt, ist es aber nur falsch, da die meisten Funktionen, die von dieser Instanz als gleich angesehen werden, nicht gleich sind!

  3. Haskell tut nicht haben als solche Überlastung überhaupt. Wenn Sie in Ihrem Modul Main eine Funktion <= definieren, ist dies eine völlig unabhängige Funktion des Standards <= aka Prelude.<=. Sie können eine solche neue Funktion definieren, aber um sie zu verwenden, müssen Sie eine eindeutige Zuordnung treffen. Folgendes sollte funktionieren:

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

    wieder aber das ist keine gute Idee, – man einfach nicht Main.<= in erster Linie definieren sollte, sondern setzte ihre Definition direkt im Ord Instanz.

+1

Würde sich die 'Ord [a]' - Instanz nicht mit der 'Prelude'-Instanz überschneiden? – chi

+0

Ich habe jetzt verstanden, was Sie bei 2 sagen. Ich habe noch eine Frage. Warum funktioniert das? Beispiel (Zeige b, Num a) => Zeige (a -> b) wo zeige f = zeige (f 0) 'und ich muss nicht 'instanz (Zeige b, Num a) = > Zeige (a -> b) wo show f = Main.show (f 0) '? – zaig

+0

Denn im Gegensatz zu '<=', das Sie scheinbar selbst neu definieren wollten, haben Sie nie Ihre eigene 'show'-Funktion definiert. Daher ist es klar, dass "show" sich auf "Prelude.show" bezieht, während "Main.show" einfach nicht existiert. – leftaroundabout