2013-09-27 78 views
8

此代碼顯然作品不使用變量< -

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") 

回答

17

因爲這不是<-是如何定義的寫。它轉化爲

readFile "in.txt" >>= \content -> 
writeFile "out.txt" (map toUpper content) 

你可以使用=<<代替:

writeFile "out.txt" . map toUpper =<< readFile "in.txt" 
3

你可以如下

readFile "in.txt" >>= writeFile "out.txt" . map toUpper 
+0

或'map toUpper <$> readFile「in.txt」>> = writeFile「out.txt」'。不過,我認爲OP要求解釋而不是單純的解決方案 – nponeccop

17

首先,<-是不是運營商。這是一個特殊的語法元素,需要在左側模式

其次,如果它是一箇中綴操作符,$ <-將不起作用,因爲您不能有兩個相鄰的中綴操作符。

6

<-「提取」來自一元容器的值。 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」版本,但它會變得非常非常困難。該符號簡化了這一點,並使編譯器爲您處理它。