2016-09-28 8 views
2

Also habe ich eine Hauptfunktion (foo), die rekursiv zwei andere Funktionen aufruft (step1 & step2). foo addiert a1 zu a2 a count mal und dann zurück (a1, a2). Wie kann ich die Variablen count, a1 und a2 bei jedem Schritt drucken?Wie drucke ich Variablen aus einer Funktion?

-- adds a1 to a2 a `count` number of times 
-- returns (a1, a2) once count reaches 0 
foo :: Integer -> Integer -> Integer -> (Integer, Integer) 
foo count a1 a2 | count == 0 = (a1,a2) 
       | otherwise = foo count' a1' a2' 
       where (count', a1', a2') = let (count'', a1'', a2'') = step1 count a1 a2 
              in step2 count'' a1'' a2'' 

-- adds a2 to a1. How to print out count, a1 and a2' here? 
step1 :: Integer -> Integer -> Integer -> (Integer, Integer, Integer) 
step1 count a1 a2 = (count, a1, a2') 
    where 
     a2' = a1 + a2 

-- decrements count by 1. How to print out count', a1 and a2 here? Or can I do these prints somewhere in the `foo` function? 
step2 :: Integer -> Integer -> Integer -> (Integer, Integer, Integer) 
step2 count a1 a2 = (count', a1, a2) 
    where 
     count' = count - 1 

Dies ist eine vereinfachte Version von Code aus einer größeren Codebasis. Ich bin offen für einen anderen Ansatz. Das Beispiel Ausgabe, die ich suche ist:

$> foo 3 4 5

(4, 17)

EDIT: ich mir wahrscheinlich nur realisiert werden Zwischenergebnisse in einer Liste speichern könnte und dann aus dieser Liste drucken. Aber muss ich meinen, ich müsste die Liste als Argument für die Funktionen übergeben?

Antwort

5

Sie müssen foo ändern und es in der IO monad arbeiten lassen. Effektiv "kennzeichnet" diese Funktion die Funktion als unrein (d. H. Sie hat einen Nebeneffekt, wie Drucken unter stdout), was es ermöglicht, Funktionen wie print aufzurufen. Hier ein Beispiel:

foo :: Integer -> Integer -> Integer -> IO (Integer, Integer) 
foo count a1 a2 = do 
    print (count, a1, a2) 
    case count of 
     0 -> do 
      print (a1,a2) 
      return (a1,a2) 
     _ -> do 
      let (count'', a1'', a2'') = step1 count a1 a2 
       (count', a1', a2') = step2 count'' a1'' a2'' 
      foo count' a1' a2' 

Hinweis: Wenn Sie diese Werte für Debugging-Zwecke ausdrucken möchten, dann können Sie Debug.Trace verwenden, wie in chepner's answer gezeigt. Sie sollten das nur für Debugging-Zwecke tun und aus keinem anderen Grund.

+0

Vielen Dank für Ihre Antwort. Dies könnte für die foo-Funktion funktionieren, aber ich müsste bei jeder der Schrittfunktionen drucken (nicht nur am Ende wie in Ihrem Beispiel). Also würde ich den Ausgabetyp von Schritt1 und Schritt2 ändern müssen, was einige Bindungsprobleme innerhalb der Foo-Funktion verursachen würde. Ideen? EDIT: Egal. Ich sehe jetzt, dass deine Lösung perfekt funktioniert. Vielen Dank. –

4

Nur zu Debuggingzwecken können Sie Debug.Trace verwenden. Zum Beispiel:

import Debug.Trace 

-- adds a2 to a1. How to print out count, a1 and a2' here? 
step1 :: Integer -> Integer -> Integer -> (Integer, Integer, Integer) 
step1 count a1 a2 = traceShowID (count, a1, a2') 
    where 
     a2' = a1 + a2 

-- decrements count by 1. How to print out count', a1 and a2 here? Or can I do these prints somewhere in the `foo` function? 
step2 :: Integer -> Integer -> Integer -> (Integer, Integer, Integer) 
step2 count a1 a2 = traceShowID (count', a1, a2) 
    where 
     count' = count - 1 

traceShowID :: Show a => a -> a ist im Grunde mit der id (unangekündigte) Nebenwirkung auch das Drucken der Zeichenfolgendarstellung Argumente gemäß show.

Verwandte Themen