此代码显然有效
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")
答案 0 :(得分:16)
因为这不是<-
的定义方式。它转换为
readFile "in.txt" >>= \content ->
writeFile "out.txt" (map toUpper content)
您可以改为使用=<<
:
writeFile "out.txt" . map toUpper =<< readFile "in.txt"
答案 1 :(得分:16)
首先,<-
不是运营商。这是一个特殊的语法元素,左侧需要模式。
其次,如果它是一个中缀运算符,$ <-
将不起作用,因为你不能让两个中缀运算符彼此相邻。
答案 2 :(得分:6)
<-
“从monadic容器中提取”一个值。 IO
是一个monad,因此可用于从IO
操作中提取值。但是,Haskell的语法表示在使用之前必须将其绑定到名称。实际上,<-
根本不是运算符,而是>>=
运算符的语法糖(发音为“bind”)。所以当你写
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”版本,但它会变得非常非常困难。该注释简化了这一点,并使编译器为您处理它。
答案 3 :(得分:3)
您可以按如下方式编写
readFile "in.txt" >>= writeFile "out.txt" . map toUpper