2013-04-14 28 views
25

私はちょうどハスケルの学習を始めましたが、ループの不在は今は無限にイライラしています。私は関数のループを書く方法を考え出しました。しかし、私の問題は、ループを反復しながらいくつかの結果を出力したいということです。私はこの単純なタスクを実行するためにデバッグを使わなければならないようです。単純なハスケルループ

これで、メインの構造で文字列を10回印刷する方法の例を理解できます。

言い換えれば、私はこの10倍をしたい:

main = do 
    putStrLn "a string" 

感謝を。私はこれが私の仕事にとって非常に明るくなると感じています。

+2

実際の質問は、関数型言語で "ループ"を実行する場合は、再帰を使用することです。厄介なのは、モナドのコンストラクタ(この場合はIO)のために型が並んでいないことです。そのため、あなたはモナドを「つなぎ合わせる」再帰的な構造が必要です。言い換えれば、これはちょうど再帰であり、ハスケルがIOを扱う「特別な」方法を処理するためのわずかなバリエーションがあります。 –

+0

私はハスケルの初心者ですが、私が得た少しの洞察を分かち合いたいと思います。誰かが、ハスケルでループを実行したいときに、再帰またはリスト内包を考えていると私に言った。あなたの質問には関係ありませんが、リスト内のすべての要素を追加したいとします。もちろん、すべての要素を反復処理する必要があります。再帰が機能し、リストの理解も使用されます。 –

答えて

36

あなたがプリント「ストリング」をn回(nは関数のパラメータである)が、このような再帰関数定義できる:

printStringNTimes 0 = return() 
printStringNTimes n = 
do 
    putStrLn "a string" 
    printStringNTimes (n-1) 

main = printStringNTimes 10 

幾分より一般的なアプローチは、その関数を定義することであろうが任意のIOアクションをn回繰り返して:

repeatNTimes 0 _ = return() 
repeatNTimes n action = 
do 
    action 
    repeatNTimes (n-1) action 

main = repeatNTimes 10 (putStrLn "a string") 

上記の機能は、すでに名前replicateM_Control.Monadに存在します。

26

まあハスケルのIOは、モナドに基づいているので、あなたがちょうど出発しているときに少しトリッキーです。これはControl.Monad

それは作曲とモナドのアクションを実行するための便利な機能の多くを持っているからコンビネータreplicateM_を使用している

main = replicateM_ 10 $ putStrLn "a string" 

あなたの問題は、しかし、単純な解決策を持っています。

+13

あなたの答えを具体的に説明する:Haskellには 'for'と' while'ループがありますが、言語組み込み関数ではなくライブラリ関数です。例えば、 'for'ループに相当するのは' Control.Monad'の 'forM_'コンビネータです。しかしこの場合、 'replicateM_'はより簡潔です。 –

+0

'Control.Monadをインポートする '必要がありますか? – vikingsteve

1

私はハスケルの初心者でもありますが、私はそれほどエレガントではありませんが、実用的には便利なソリューションを用意しています。

ここでは、リストを定義しました。その要素は、印刷する文字列とそれに続く改行文字です。