1

Ich lerne Haskell und versuche, dieses Programm zu implementieren. Ich habe einen benutzerdefinierten DatentypVergleich des benutzerdefinierten Datentyps mit Parametern

data CalculatorInput 
    = Exit 
    | Error String 
    | Operator (Int -> Int -> Int) 
    | Number Int 

dann habe ich eine Methode getInput, die einen Wert dieses Typs zurückgibt.

Jetzt bin ich verwirrt, wie man auf Werte dieses Typs versendet. Ich habe eine Methode

simpleCalculator :: Int -> (Int -> Int -> Int) -> IO() 
simpleCalculator ans op = do 
    input <- getInput -- here i got the type as result 
    if input == Exit then return() 
    else if input == Number x then ans = ans op x; print ans 
    else simpleCalculator ans op 

Ich möchte wissen, ob die Eingabe eine Number x

ist

Ich versuchte case auch zu verwenden:

simpleCalculator :: Int -> (Int -> Int -> Int) -> IO() 
simpleCalculator ans op = do 
    input <- getInput -- here i got the type as result 
    --case input of 
    -- Exit -> return() 
    -- Error x -> print x 
    -- Number n -> ans = ans op x; print ans -- getting error here, multiple statement not possible 
    -- _ -> simpleCalculator ans op 

Ich versuchte Instanz Eq auch

zu erstellen
instance Eq CalculatorInput where 
    (==) Exit Exit = True 
    (==) (Number x) (Number y) = x == y 
    (==) _ _ = False 

Wie kann ich benutzerdefinierte Daten vergleichen Typen mit Parametern oder haben mehrere Anweisungen in einem case Zweig?

+0

@MathematicalOrchid. es hat nicht funktioniert. Ich habe es versucht. und ich bemerke auch, dass es zu inifnite loop auf let ans geht = op ans n –

+1

@WaqarAhmedm 'let ans = op ans n '- Dies * rekursiv * definiert' ans' in Bezug auf sich selbst. Sie müssen einen neuen Namen verwenden, in diesem Fall verwenden wir oft eine Primzahl '' ':' let ans '= op ans n' – luqui

+0

@ luqui..ich habe es..danke. eine weitere Frage, warum es gut ist, keinen Wert von der SimpleCalculator-Methode zurückzugeben? –

Antwort

1

Sie sind fast auf dem richtigen Weg mit dem nicht funktionierenden Code:

simpleCalculator :: Int -> (Int -> Int -> Int) -> IO() 
simpleCalculator ans op = do 
    input <- getInput -- here i got the type as result 
    case input of 
     Exit -> return() 
     Error x -> print x 
     Number n -> ans = ans op x; print ans 
     _ -> simpleCalculator ans op 

Sie können Nest do Notationen so dass Sie das folgende richtige Programm schreiben:

simpleCalculator :: Int -> (Int -> Int -> Int) -> IO() 
simpleCalculator ans op = do 
    input <- getInput -- here i got the type as result 
    case input of 
     Exit -> return() 
     Error x -> print x 
     Number n -> do 
     let theAns = ans op x 
     print theAns 
     _ -> simpleCalculator ans op 

Wie für die Eq Instanz kann der Compiler die Arbeit für Sie erledigen, indem er derivation verwendet, dh

data CalculatorInput 
    = Exit 
    | Error String 
    | Operator (Int -> Int -> Int) 
    | Number Int 
    deriving Eq 
schreiben
+0

Hallo Kaktus, ich versuchte gestern dieselbe Logik und es funktionierte. aber ich bin verwirrt, wenn ich ans = ans op x verwende. es geht zur Endlosschleife. Kannst du mir bitte sagen, warum es passiert? –

+0

Das ist, weil wenn Sie "let ans = ans op x" machen, das 'ans' auf der rechten Seite auf das selbe ans bezieht. – Cactus

+0

Danke, ich habe es ... eine weitere Frage, warum es gut ist, nicht Wert von Methode wie in diesem Fall SimpleCalculator-Methode zurückzugeben? –

0

Verwenden Sie case.

simpleCalculator ans op = do 
    input <- getInput -- here i got the type as result 
    case input of 
     Exit -> return() 
     Number x -> print $ans `op` x 
     _ -> simpleCalculator ans op 

Sie können Eq für CalculatorInput nicht ableiten, da die Funktionen nicht Instanzen von Eq sind.

+0

Ich mache das schon so. Wie führe ich mehrere Anweisungen im Switch Case aus? –

+0

Bitte meinen Code sehen. In Haskell führen Sie keine Anweisungen aus. Sie werden angegeben, nicht ausgeführt. – bipll