3

私は Haskell の初心者で、現在 LearnYouAHaskell を使用しています。空白で区切られた文字列を取り、それをより小さな単語文字列のリストに分割しようとしています。私の現在のプログラム:

main = do 
    putStrLn "Insert a string to convert: "
    -- Input string
    line <- getLine
    words line;

しかし、この場合、IO エラーが発生していることがわかります。私の理解では、 getLine はアクションなので、これは不純なので、「行」にバインドする必要があります。Line は、IO String である getLine の正確な表現です。

しかし、 line は文字列であってはいけませんか? オンラインで単語を使用しようとすると、「予想される型 "IO a0" を実際の型 [String] と一致させることができませんでした」と表示されます

行が文字列ではないかのように。さらに、実際の型が正しいかどうかを確認するためにプログラムを作成するときに、プログラム自体で :t 行を使用できますか?

初心者の質問で申し訳ありませんが、少し行き詰まっています。

編集:

私はGHCIで似たようなことをしました.それは私の型が実際には通常の文字列であることを教えてくれます..私はそれを理解していません.

Prelude> line <- getLine
"Hello fellows"
Prelude> :t line
line :: String
Prelude> words line
["Hello","fellows"]

なぜそれがうまくいかないのですか?

4

2 に答える 2

7

Haskell では、値を返したい場合は、次のように言わなければなりません。

main = do 
    putStrLn "Insert a string to convert: "
    -- Input string
    line <- getLine
    return (words line)

words linedoは IO アクションではなく、文字列のリストであるため、ブロック内のステートメントにすることはできません。

return :: Monad m => a -> m aこの場合、型に特化してから に特化できa -> IO aます[String] -> IO [String]doブロック内の各ステートメントはステートメントでなければなりませんIO


それをさらに進める:

プログラムをコンパイルしたい場合は、 が必要main :: IO()です。つまり、リストを返すべきではありません。

たとえば、processこれらの文字列を単一の文字列にしたい場合は、それを出力します。

process :: [String] -> String
process xss = "I don't know, some answer"

main = do 
    putStrLn "Insert a string to convert: "
    -- Input string
    line <- getLine
    putStrLn (process (words line))

個人的には最後の行をputStrLn $ process.words $ line.


GHCi でのやり取り

Prelude> line <- getLine
"Hello fellows"
Prelude> :t line
line :: String
Prelude> words line
["Hello","fellows"]

GHCi が実際には IO モナドで実行されているだけではないという事実を利用しています。GHCi では、入力がブロック内の有効な行であるdo場合は実行されますが、純粋なコードの場合は評価されて出力されます。(このような対話型インタープリターは、R​​ead-Eval-Print-Loop の REPL と呼ばれることがよくあります。)

于 2013-02-05T22:23:05.163 に答える
3

さて、問題はあなたが何をしたいwords lineですか?

words linedo ブロック内の行としては何もしませんが、それを機能させるには、IO モナドでラップするために使用する必要がありますreturn

main = do 
    putStrLn "Insert a string to convert: "
    -- Input string
    line <- getLine
    return (words line);

とにかく、代わりに印刷したいですか?

main = do 
    putStrLn "Insert a string to convert: "
    -- Input string
    line <- getLine
    print (words line);
于 2013-02-05T22:23:55.037 に答える