このコードは明らかに機能します
import Data.Char
main = do
content <- readFile "in.txt"
writeFile "out.txt" (map toUpper content)
なぜこれはしないのですか?
import Data.Char
main = do
writeFile "out.txt" (map toUpper $ <- readFile "in.txt")
このコードは明らかに機能します
import Data.Char
main = do
content <- readFile "in.txt"
writeFile "out.txt" (map toUpper content)
なぜこれはしないのですか?
import Data.Char
main = do
writeFile "out.txt" (map toUpper $ <- readFile "in.txt")
<-
これは定義方法ではないためです。訳すと
readFile "in.txt" >>= \content ->
writeFile "out.txt" (map toUpper content)
代わりに使用できます=<<
:
writeFile "out.txt" . map toUpper =<< readFile "in.txt"
まず、<-
オペレーターではありません。これは、左側にパターンを必要とする特別な構文要素です。
第 2 に、$ <-
2 つの中置演算子を隣り合わせにすることはできないため、中置演算子の場合は機能しません。
は<-
、モナド コンテナから値を「抽出」します。 はモナドなので、アクションIO
から値を抽出するために使用できます。IO
ただし、Haskell の構文では、使用する前に名前にバインドする必要があります。実際には、<-
は演算子ではなく、演算子の構文糖衣です>>=
(「バインド」と発音します)。だからあなたが書くとき
main = do
contents <- readFile "in.txt"
writeFile "out.txt" (map toUpper contents)
それはに変わります
main = readFile "in.txt" >>= (\contents -> writeFile "out.txt" (map toUpper contents))
ここで、 にさらに多くのステートメントがあると想像してくださいmain
。で複数の値を抽出し<-
、一部の式で一度に複数の値を使用した可能性があります。「脱糖」バージョンを書くことは間違いなくできますが、非常に困難になり始めます。do 表記はこれを単純化し、コンパイラーに処理させます。
次のように書くことができます
readFile "in.txt" >>= writeFile "out.txt" . map toUpper