2016-07-21 5 views
0

Ich habe ein einfaches Problem. Dieser Code sieht für mich vollkommen in Ordnung aus.Haskell Basic Show Instanz für einfache rekursive Datentyp nicht funktioniert

main = do 
     print("10-2") 
     let a = L 
     let b = E "abc" a 
     print(a) 
     print(b) 


    data List a = L | E a (List a) 

    instance (Show a) => Show (List a) where 
     show L = "Empty" 
     show (E a list) = (show a)++ (show list) 

Aber es erzeugt Fehler folgende:

10-2.hs:5:5: 
    No instance for (Show a0) arising from a use of `print' 
    The type variable `a0' is ambiguous... 

Ich kann nicht das Problem finden. Danke für die Hilfe!

Antwort

4

Es ist der gleiche Fehler, den Sie erhalten, wenn Sie versuchen, dieses einfache Programm zu kompilieren:

main = print [] 

Was? Haskell kann keine leere Liste drucken? Das stimmt, das kann nicht. Das heißt, es sei denn, der Typ des Listenelements ist bekannt. Es ist in diesem Fall nicht bekannt, so dass die Kompilierung fehlschlägt. Um warum, führen diese beiden Programme zu sehen:

main = print ([] :: [Int]) 
main = print ([] :: [Char]) 

Der Ausgang ist anders, wenn der einzige Unterschied zwischen diesen Programmen die Art der eine leere Liste ist.

jedoch, wenn Sie in ghci das gleiche mehrdeutig Programm versuchen, wird es [] ganz gut drucken!

Prelude> let main = print [] 
Prelude> main 
[] 
Prelude> 

Dies liegt daran, ghci eine etwas liberalere Satz von defaulting rules als ghc hat. Also, wenn Sie Ihre Datentypdefinition zu ghci laden und sagen print L an der Eingabeaufforderung, wird ghci glücklich gehorchen:

[1 of 1] Compiling Main    (h.hs, interpreted) 
Ok, modules loaded: Main. 
*Main> print L 
Empty 
*Main> 
+0

Danke für die Antwort.Aber für meine List-Type ist der leere Ausdruck definiert. Es sollte keinen Unterschied machen. Das L kann nur von meinem Datentyp sein. Kann es nicht sein? Die seltsame Sache, die ich fand, war:: t L ist Liste –

+0

@PaulOskarMayer Es gibt keine nur Liste, es kann nur Liste von * etwas *. Sie müssen sagen, was ich das * etwas *, bevor Sie drucken können. Hast du den angegebenen Link gelesen? –

+0

Ja ich denke ich weiß was du meinst. Sie beziehen sich auf sofortige Bewertung? Wird die Liste nur ausgefüllt, wenn mehr als ein Konstruktor vorhanden ist? –

4

In Ihrer Funktion main, wenn Sie let a = L schreiben, ist der Typ a nur List a0. Wenn der Compiler versucht herauszufinden, welche Version der Show Instanz er verwenden soll, passen alle Typen, weil der Typ a nicht vollständig definiert ist. Wenn Sie jedoch die Zeile print a löschen, werden Sie sehen, dass print b funktioniert, weil der Typ b nur List String sein kann und der Compiler genau weiß, welche Version von show er verwenden muss. Versuchen

main = do 
    print "10-2" 
    let a = L 
    let b = E "abc" a 
    -- print a 
    print b 

print [] schreiben und Sie werden sehen, dass die Compiler Ihnen die gleiche Art von Fehler gibt.

In Ghci jedoch, wenn Sie nur print L oder print [] eingeben, wird kein Fehler angezeigt. Ich weiß nicht, warum das passiert.

+3

Es ist wegen der GHCi des [erweitert säumige Regeln] (http: //ghc.readthedocs.io/de/8.0.1/ghci.html#type-defaulting-in-ghci). –

+0

Danke @ReinHenrichs !!! Große Erklärung –

1

Wie die anderen schon gesagt, müssen Sie Ihre Liste eine Art geben, selbst wenn die Daten Constructor Doesn brauche es nicht, um sich selbst zu erschaffen.

So ausprobieren:

print (L :: List Int) 

oder was auch immer Sie mögen nur Ihre String of the Show Instanz (List a) drucken