ハスケルではかなり簡単です。最も難しいのは、ユーザー入力のシーケンスを累積したいということです。命令型言語ではこれを行うためにループを使用しますが、Haskellでは標準的な方法は再帰的ヘルパー関数を使用することです。
getUserLines :: IO String -- optional type signature
getUserLines = go ""
where go contents = do
line <- getLine
if line == "q"
then return contents
else go (contents ++ line ++ "\n") -- add a newline
これは実際String
を返すIOアクションの定義である:それは次のようになります。それはIOアクションなので、=
代入構文ではなく、<-
構文を使用して返された文字列にアクセスします。概要を知りたい場合は、The IO Monad For People Who Simply Don't Careとお読みください。
あなたが
import Control.Applicative ((<$>))
input <- unlines . takeWhile (/= "q") . lines <$> getContents
ような何かを行うことができ
>>> str <- getUserLines
Hello<Enter> -- user input
World<Enter> -- user input
q<Enter> -- user input
>>> putStrLn str
Hello -- program output
World -- program output
今、あなたは本当にハスケルでこれを書いていますか?毎回 'content'に' line'を付けるとパフォーマンスが悪くなります。あなたが最後に望む 'contents'は、' getContents'への一回の呼び出しが与える接頭辞です。 – nickie
それはかなりのポイントですが、IOモナド(これはおそらく初心者のためにハスケルの最も混乱している部分です)で作業するための感触を得るために、これを "最初から"行う方法を説明する価値があると思いました。また、ユーザーの入力を入力から分離するという利点もありますが、入力には処理が含まれていません。 'getContents.'についての付録を追加します。 –
OK、要点、私は最初の-1を取り戻しています。しかし、教育の目的は別に残して、私はこの悪いハスケルのようなコードを検討したいと思います。気になる人のために、少なくとも... :-) – nickie