此代码显然作品不使用变量< -
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"
你可以如下
readFile "in.txt" >>= writeFile "out.txt" . map toUpper
首先,<-
是不是运营商。这是一个特殊的语法元素,需要在左侧模式。
其次,如果它是一个中缀操作符,$ <-
将不起作用,因为您不能有两个相邻的中缀操作符。
<-
“提取”来自一元容器的值。 IO
是一个monad,因此它可用于从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
有很多条语句。也许你用<-
提取了几个值,并且某些表达式同时使用了多个这些值中的一个。你完全可以写出“desugared”版本,但它会变得非常非常困难。该符号简化了这一点,并使编译器为您处理它。
或'map toUpper <$> readFile“in.txt”>> = writeFile“out.txt”'。不过,我认为OP要求解释而不是单纯的解决方案 – nponeccop