2012-03-12 24 views
3

私はコードを持っている:私は何をしたいかHaskellのIO再帰

read :: IO [Line] 
read = do 
    line <- getLine 
    let count = length line 
    line2 <- getLine 
    if (length line2 /= count) 
    then error "too long or too short" 
    else read 

は、ユーザが入力長-1行以上を しなければならない最初の行の長さに基づいて、ある、また、それらのいずれかの場合を行の長さが同じでない場合は、エラーメッセージが表示されます。

今、私のコードは無限ループです。 長さ-1の行を入力する方法はわかりません。これについてのいくつかの指針は認められるでしょう。

編集:ラインは、String型

+0

あなたのコードが無限ループである理由は、それを停止させる唯一の方法はエラーです。さもなければ、それは常にifステートメントの他のブランチに続き、何度も繰り返し再帰します。 –

答えて

5

あなたは結果をアクションに設定された回数を複製し、収集するためにreplicateMを使用することができるのです。あなたのケースでは、行を取得し、その長さをテストし、無効であればエラーを処理します。したがって、あなたの仕事を達成するために、次のようなものを使用することができます:

import Control.Monad (replicateM) 

read :: IO [Line] 
read = do 
    line <- getLine 
    let count = length line 
    lines <- replicateM (count-1) $ do 
    line <- getLine 
    if length line /= count 
    then fail "too long or too short" 
    else return line 
    return $ line : lines 
+0

ありがとう! ReplicateMは必要に応じて停止しないようですが(count-1の制限を超えています!) – gdrules

+2

replicateMは完全に動作しますが、問題がある場合はおそらく残りのコードにあります。単純なコードの標準的な部分が、その目的を完全に失っているように見える場合、標準的な機能を責めたり、自分のコードでエラーを探したりすることは、合理的な立場です。それでもエラーが見つからない場合は、経験豊富なHaskeller、ここまたは#haskellにコードを公開してください。それでもエラーが見つからない場合は、標準ライブラリの疑義を開始するときです。 – Jedai

+0

私は、上記のコードは私にはうまく見えると思うが、私は修正を見つけることができるかどうかを確認するために調整を続けるだろう...ありがとう – gdrules