2016-09-28 6 views
2

私は再帰的に2つの他の関数(step1 & step2)を呼び出すメイン関数(foo)を持っています。 fooはa1をa2に追加し、countの時間量を返してから(a1、a2)を返します。各ステップで変数count、a1、a2をどのように出力できますか?関数内から変数を出力するにはどうすればよいですか?

-- 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 

これは、より大きなコードベースのコードの簡略化されたバージョンです。私は別のアプローチを使用することにオープンです。私が探しています出力例は次のとおりです。

$> fooという3 4 5

(4、17)

編集:私はちょうど私はおそらく、リスト内の中間結果を格納し、そのリストから印刷可能性が実現。しかし、関数の引数としてリストを渡さなければならないと思うのは正しいですか?

答えて

5

fooを変更して、IOモナドで動作させる必要があります。効果的に、これは、機能が不完全である(すなわち、stdoutに印刷するなどの副作用を有する)として機能し、printなどの関数を呼び出すことができます。ここでは例です:

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' 

:あなたはデバッグ目的のために、これらの値を印刷したい場合はchepner's answerに示すように、あなたはDebug.Trace使用することができます。デバッグを目的としているだけで、それ以外の理由はありません。

+0

ありがとうございます。これはfoo関数ではうまくいくかもしれませんが、私は各ステップ関数(あなたの例のように最後ではなく)で印刷する必要があります。ですから、step1とstep2の出力タイプを変更する必要があります。これは、foo関数の内部でいくつかのバインディングの問題を引き起こします。アイデア? 編集:気にしないでください。私は今あなたのソリューションが完璧に動作することを知ります。どうもありがとうございました。 –

4

デバッグの目的でのみ、Debug.Traceを使用できます。例えば:

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は、基本的にもshowに係る引数の文字列表現を印刷する(抜き打ち)副作用とidあります。

関連する問題