2017-01-30 26 views
1

Was ich zur Zeit versucht, eine Art Value genannt zu tun ist, erstellenMatching erwarteten Typ mit tatsächlichen Typ

eval :: Value -> Int 
eval (Num x) = x 
eval (Sum x y) = x + y 
eval (Dif x y) = x - y 
eval (Neg x) = -x 

Meine erwarteten Ergebnisse sein sollte:

eval $ Dif (Sum (Num 3) (Num 6)) (Neg 4) 
> 13 

Mit meinem aktuellen Code ich bin jeden Betreiber von themselve testen können s und sie funktionieren.

eval (Dif 3 4) 
>-1 

Das Problem entsteht, wenn ich versuche, die verschachtelten Operationen in der erwarteten Eingabe auszuführen oben, wie ich dann den Fehler:

"Couldn't match expected type Int with actual type Value "

Ich versuche, das Problem zu verstehen, wie ich meinen Betrieb gedacht sollte eine Int zurückgeben und da meine Value Typen eine Int nehmen, sollte die nächste Operation den erwarteten Typ haben. Ich habe verschiedene Eingänge getestet, um zu sehen, was meine aktuelle Funktion eval tatsächlich tut, und festgestellt, dass, wenn ich

eval (Dif (eval (Sum 3 5)) 4) 
>4 

ich das erwartete Ergebnis. Was mache ich hier falsch?

+0

Warum versuchen Sie, einen "Wert" in etwas zu setzen, das ein 'Int' nimmt 'Sum (Num 1) (Num 2)' funktioniert nicht, weil "Num 1 :: Value" aber "Sum" ein "Int" erwartet. – AJFarmar

+1

Abgesehen von der richtigen Antwort, die Sie bekommen haben, sollten Sie in make 'Value' eine Instanz von' Num' suchen - so können Sie '1 :: Value' schreiben. – Alec

+1

Ich habe völlig übersehen, dass ich Value-Typen tatsächlich einging; Ich war in der falschen Einstellung AJFarmer (Ich werde es für Mangel an Schlaf verantwortlich machen). Mein Beitrag wurde bearbeitet, aber ich bin neu in Haskell, also bin ich einfachen Fehlern erlegen. Danke für den Tipp Alec! – Sinsarii

Antwort

6
data Value = Num Int 
      | Sum Int Int 
      | Dif Int Int 
      | Neg Int 

Hier haben Sie angegeben, dass die Value Konstrukteure auf Int Werte nur dann funktionieren, zum Beispiel hat Neg den Typ Int -> Value. So können Sie nicht etwas wie Neg (Neg 1) oder Sum (Num 1) (Num 2) schreiben, weil Sie versuchen, ein getaggtes Value zu verwenden, wo ein unmarkiertes Int erwartet wird. In Lisp wäre es so, als ob Sie (Num . 1) übergeben haben, wenn eine Funktion nur 1 erwartet.

Sie können die Definition Ihrer Typ verändern Value zu akzeptieren:

data Value = Num Int 
      | Sum Value Value 
      | Dif Value Value 
      | Neg Value 

Nun stellt dies Ausdrücke, wo Num ist eine wörtliche Int aber die anderen Konstrukteure arbeiten auf Value s. Dann ändert sich die eval Funktion entsprechend:

+1

Danke dafür! Ich las den Abschnitt einfach neu und realisierte, was ich getan hatte. Ihre Erklärung war perfekt, danke! – Sinsarii

Verwandte Themen