2017-03-13 4 views
0

Wir sind in einer SImpL.hs Datei angegebenen Code sind, die die folgenden Daten Konstrukteuren und Typen enthält:Neuformatierung ein Konstruktortyp Programm Haskell Daten und Neuformatierung

module SImpL where 

data AExprT = ALit ValT -- a literal value (an Int) 
       | AName NameT -- a variable name (a String) 
       | Add AExprT AExprT -- one arithmetic expression added to another 
       | Sub AExprT AExprT -- one arithmetic expression subtracted from another 
       | Mult AExprT AExprT -- one arithmetic expression multiplied by another 
       deriving (Show,Eq) 

data BExprT = BLit Bool -- a literal value (True or False) 
       | Eq AExprT AExprT -- an equality test between two arithmetic expressions 
       | Less AExprT AExprT -- a "less than" test between two arithmetic expressions 
       | Greater AExprT AExprT -- a "greater than" test between two arithmetic expressions 
       | Not BExprT -- the negation of a boolean expression 
       | And BExprT BExprT -- the "and" of two boolean expressions 
       | Or BExprT BExprT -- the "or" of two boolean expressions 
       deriving (Show,Eq) 

type ValT = Integer 

type NameT = String 

data StmtT = Assign NameT AExprT | 
      If BExprT StmtT StmtT | 
      While BExprT StmtT | 
      Seq [StmtT] -- If the list is empty, this is a statement that does nothing.  
      deriving (Show,Eq) 

If BExprT StmtT StmtT | 
      While BExprT StmtT | 
      Seq [StmtT] -- If the list is empty, this is a statement that does nothing.  
      deriving (Show,Eq) 

type ProgT = StmtT 

type StateT = [(NameT, ValT)] 

Wir bitten die diese Aufgabe zu machen:

Schreiben Sie eine Funktion namens changeName, die ein SImpL-Programm (ein Wert vom Typ StmtT) nimmt und eine Kopie dieses Programms mit einem der geänderten Variablennamen zurückgibt. Diese Funktion sollte drei Parameter haben: zwei Strings und ein SImpl-Programm. Die Strings repräsentieren Variablen Namen. Ihre Funktion sollte eine Kopie des Programms mit allen Instanzen der ersten Zeichenfolge, die durch die zweite Zeichenfolge ersetzt wurde, zurückgeben. Für Beispiel eine Java-ähnliche Notation, wenn MyProgram stellt dieses Programm:

x = 3 
y = 14 
z = 0 
while (x < y) 
    z = z + x*y 
    x = x + 1 
answer = z + y 

das Ergebnis Change "x" "number" MyProgram eine Darstellung dieses Programms sein sollte:

number = 3 
y = 14 
z = 0 
while (number < y) 
    z = z + number *y 
    number = number + 1 
answer = z + y 

Ihre Change Funktion benötigen einen Fall für jede Art vonhabenAnweisung in der Sprache SImpL und Sie benötigen eine Hilfsfunktion zu ändern Sie die Namen der Variablen in Ausdrücken.

Der Pseudo-Code, den ich gearbeitet habe, um nach oben ist hier unten:

module Assignment3 where 

import SImpL 

changeName :: String -> String -> StmtT -> StmtT 
changeName val1 val2 (Assign NameT AExprT) = ... 
changeName val1 val2 (If BExprT StmtT StmtT) = ... 
changeName val1 val2 (While BExprT StmtT) = ... 
changeName val1 val2 (Seq [StmtT]) = ... 

Während ich denke, dass ich den grundlegenden Kern dies zu verstehen, ich bin ganz auf der tatsächlichen Umsetzung des Codes verloren. Wenn Sie zum Beispiel diesen Code ausführen:

changeName "x" "num" testMyProgram... 

wo testMyProgram einfach ist

Assign "x" (ALit 3) 

Ich weiß nicht, wie Haskell zu bekommen eine Reihe von StmtT-Code zurück, wie zum Beispiel:

Assign "num" (ALit 3) 

Ich bin mir ziemlich sicher, das ist, was der Lehrer von den Anweisungen will.

+0

Als Fußnote ...Ich werde es ununterbrochen betrachten und zurückkommen, wenn ich es tatsächlich herausfinde, aber ich habe es stundenlang angeguckt ... –

Antwort

2

Sie müssen eine Funktion erstellen, die einen Begriff dekonstruiert, und wenn eine seiner Komponenten ersetzt werden muss, erstellen Sie einen neuen Begriff.

changeNameStmt x y (Assign a b) | x == a = Assign y (changeNameExpr x y b) 
           | otherwise = Assign a (changeNameExpr x y b) 
... 

Expr Da kann auf Variablen beziehen sich auch, ist es notwendig, in sie Rekursion und alle Vorkommen dort zu ersetzen.

changeNameExpr x y (Name n) | x == n = Name y 
... 
changeNameExpr x y (Add a b) = Add (changeNameExpr x y a) (changeNameExpr x y b) 

Tun Sie dies für alle Arten, die in Aussagen beteiligt sind. Sie können eine Klasse definieren und die Typen Instanzen davon machen, wenn Sie eine polymorphe changeName möchten.

+0

Danke, ich glaube, ich verstehe deinen Code und den ersten Dekonstruktionsteil, aber ich bin es nicht sicher, was changeNameExpr xyb tut. Könnten Sie näher erläutern, warum es nicht ausreicht, Assign y b zurückzugeben? –

+0

Ich habe meine Antwort aktualisiert – jakubdaniel

+0

Ah, ich glaube ich verstehe jetzt, danke für die Klarstellung. Müssen wir Show- und EQ-Fälle in "changeNameExpr" einschließen, da sie abgeleitet sind? –

Verwandte Themen