3

ユーザーが文字列のリストを入力できるようにする関数を作成しようとしています。この関数は長さを受け取り、ユーザーが length-1 行を入力できるようにします。次に、各行をチェックして、元の行と同じ長さであることを確認します。ただし、いくつかの問題があり、解決策が見つかりません。

問題は、count-1 行よりも多く入力でき、長さが期待どおりに計算されないことです。たとえば、["12","13"] を入力してから ["121","13" を入力した場合] 同じ長さですが、エラーが発生します!

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

行は文字列型です。

readLn は解析エラーを返します。

4

1 に答える 1

5

String行をaとして取得することと、入力行をカスタムタイプとして読み取る/解析することの違いについて、混乱しているように思えます。を使用しています。これは、ユーザーが入力しgetLineたものを常に正確に返しますString。比較:

Prelude> fmap length getLine
["12","13"]
11
Prelude> length "[\"12\",\"13\"]" -- explanation of the 11
11
Prelude> fmap length (readLn :: IO [String])
["12","13"]
2
Prelude> length ["12", "13"] -- explanation of the 2
2

ここで示されているように、おそらく、を使用する必要がありますreadLn。これは、最初に入力行を取得し、次にそれを。で解析しreadます。

-- defined in the Prelude
readLn = do
    s <- getLine
    return (read s)

以下のインポートと定義を含めるようにコードを変更した場合:

import Control.Monad
type Line = [String]

readLn...そして、の代わりに呼び出すためにgetLine、私は文字通りの行をエラーなしで入力することが["12","13"]でき["121","13"]ます。

于 2012-03-12T11:35:29.933 に答える