2017-10-16 3 views
1

Ich habe meinen eigenen Haskell-Datentyp geschrieben, um eine Summenoperation mit ganzen Zahlen aufzulösen, aber ich weiß nicht, wie ich die Semantik machen soll.Haskell - arithmetische Operationen mit Datentypen

data Expr = Value Int 
    | Sum Expr Expr 

Ich habe versucht zu tun:

sum:: Expr -> Expr -> Int 
sum a b = b + a 
val:: Int -> Int 
val a = a 

Ich mag schreiben wollen:

Sum (Value 3) (Value 5) 

und 8 als dafür bekommen, irgendwelche Ideen?

+0

Was ist passiert, als Sie es versucht haben? –

+1

'Sum (Wert 3) (Wert 5)' wird * immer *, definitionsgemäß, ein eindeutiger Wert vom Typ 'Expr' sein; Sie können es nicht auf '8' reduzieren, da '8' kein Konstruktor für' Expr' ist. – chepner

Antwort

0

Sie müssen sum passend für jede Kombination von Datenkonstruktoren definieren.

sum :: Expr -> Expr -> Int 
sum (Value x) (Value y) = x + y 
sum (Sum a b) (Sum c d) = sum a b + sum c d 
sum (Value x) (Sub a b) = x + sum a b 
sum (Sum a b) (Value y) = sum a b + y 

Dies kann vereinfacht werden; Ein Weg ist mit einer Hilfsfunktion, die einen einzelnen Expr zuerst auf einen ganzzahligen Wert reduziert.

value :: Expr -> Int 
value (Value x) = x 
value (Sum x y) = (value x) + (value y) 

sum :: Expr -> Expr -> Int 
sum x y = value x + value y  
4

Typischerweise in einer solchen Situation, schreiben Sie eine "Auswerter" oder "Interpreter" - eine einzige Funktion, die eine Expr und wertet sie auf einen Wert annimmt:

eval :: Expr -> Int 

Dann

> eval (Sum (Value 3) (Value 5)) 
8 
> 

Haskells pattern-Matching-Definitionen für die Funktion dieses sehr elegant macht: Sie können schreiben

eval (Value x) = ... 
eval (Sum e1 e2) = ...you'll need to use eval recursively here... 

Anstatt also mehrere Funktionen des Schreibens, eine für jede Komponente Ihrer Expr, schreiben Sie eine einzelne Funktion mit einem musterbasierte Definition für jede Komponente.

Wenn dies Hausaufgaben waren, möchten Sie vielleicht hier aufhören und versuchen, die Details selbst herauszufinden. Wenn nicht, dann sollte folgendes funktionieren:

eval :: Expr -> Int 
eval (Value x) = x 
eval (Sum e1 e2) = eval e1 + eval e2 
+0

Yay, du hast mich gerettet. Ihr Vorschlag funktioniert gut = D –

Verwandte Themen