getLine関数を呼び出します。IO a - > aから関数を書く?
それは私がこのIO値から文字列を抽出するにはどうすればよいタイプ
getLine :: IO String
を持っています。より一般的には、どのように変換するのですか?これに
IO a
:
a
これが不可能な場合。なぜ私はこれをすることができないのですか? Haskellで
getLine関数を呼び出します。IO a - > aから関数を書く?
それは私がこのIO値から文字列を抽出するにはどうすればよいタイプ
getLine :: IO String
を持っています。より一般的には、どのように変換するのですか?これに
IO a
:
a
これが不可能な場合。なぜ私はこれをすることができないのですか? Haskellで
、あなたがIO
に「閉じ込められた」されている値で作業したい場合、あなたはIO
外の値を取ることはありません。代わりに、実行する操作をIO
に入れます。
たとえば、Preludeのlength
関数を使用して、getLine :: IO String
が生成する文字の数を確認したいとします。
fmap :: (a -> b) -> IO a -> IO b
それはIO
中に閉じ込められていない「純粋な」値で動作機能を取り、あなたの機能を提供します:
そこには、ヘルパー関数は、型を持っていたときに、特殊なIO
に、fmap
と呼ばれる存在しますIO
にトラップされた値で動作します。これは、コード
fmap length getLine :: IO Int
は、コンソールから行を読み込みIO
アクションを表していることを意味して、あなたにその長さを与えます。
<$>
は、事物を簡単にすることができるfmap
のインフィックスシノニムです。これは、上記のコードと同等です:今
length <$> getLine
、あなたがIO
-trapped値を返しますIO
-trapped値自体で実行したい時々操作。簡単な例:あなたが読み込んだ文字列をputStrLn :: String -> IO()
を使って書き戻すことをやめましょう。
この場合、fmap
では不十分です。 IO
に特化した場合は、IO a -> (a -> IO b) -> IO b
となる(>>=)
演算子を使用する必要があります。うちの場合:
getLine >>= putStrLn :: IO()
がチェーンにIO
アクションを(>>=)
を使用することは不可欠で、シーケンシャルな風味を持っています。より自然な方法でこのような一連の動作を記述するのに役立ちます"do-notation"と呼ばれるシンタックスシュガーのようなものがあります:ここ<-
が行うが提供する事業者が、シンタックスシュガーの一部ではないことを
do line <- getLine
putStrLn line
お知らせ表記
このよくある質問の簡単な説明「代わりに、実行したい操作をIOに入れます!」 – luqui
Cを知っている場合は、「文字列をgets
から取得するにはどうすればよいですか? IO String
は入手困難な文字列ではなく、ネットワークや標準入力からの文字列のような読み込みを返す手続きです。 文字列を取得する手順を実行します。あなたが望むしかし、値を使用し、その後String
値を得ることがgetLine
操作を実行して上記で
main = do
someString <- getLine
-- someString :: String
print someString
:順番にIOアクションを実行するための
一般的な方法は、do
表記です。
do
ブロック内にいる場合、<-
をIOから値を取得すると(非公式に/不正確に)考えることができます。例えば
は、以下の機能がgetLine
から行を取り、単なる文字列
main = do
line <- getLine
putStrLn (wrap line)
wrap :: String -> String
wrap line = "'" ++ line ++ "'"
あなたはwrap
としてこれをコンパイルした場合は、コマンドラインの実行にかかり、純粋な関数に渡し
echo "Hello" | wrap
あなたは見るべき
'Hello'
「一般的に」、このタイプの関数が必要な理由は不明です。この場合、すべての違いが生じます。
可能であることを完全に記しておく必要があります。実際にはunsafePerformIO
と呼ばれるタイプライブラリIO a -> a
の機能がベースライブラリに存在します。
しかし、理由のためにunsafe
部分があります。その使用法が正当とみなされる状況はほとんどありません。それは非常に慎重に使用されるエスケープハッチです - ほとんどの時間あなたは自分自身を出す代わりにモンスターを許可します。
通常、IO a
からa
に移動できないのはなぜですか?まあ、少なくとも純粋ではない一見純粋な機能を持つことによってルールを破ることができます。これを行うことが一般的なプラクティスであった場合は、型シグネチャとコンパイラによって検証されたすべての作業が意味をなさないでしょう。すべての正しさの保証は窓から出るでしょう。
これは(通常)不可能なので、ハスケルは、部分的に面白いです。
あなたのgetLine
の問題にどう対処するかについては、他の回答を参照してください。
これを行うことができれば、最初にIOタイプを持つことに意味がないためです。 – sepp2k
重複してしまう:[* HaskellでIO Stringを解析するには?*](http://stackoverflow.com/q/11229854/2751851)重複ターゲット)。 – duplode