據我所知,Haskell中的do
塊只是單子綁定操作符的某種語法糖。例如,人們可以使用唯一的一元綁定語法表達do塊
main = do f <- readFile "foo.txt"
print f
print "Finished"
轉換爲
main = readFile "foo.txt" >>= print >> print "Finished"
是否所有do
塊轉換的綁定語法?怎麼樣,例如,該塊在那裏f
多次使用:
main = do f <- readFile "foo.txt"
print $ "prefix " ++ f
print $ f ++ " postfix"
假設我們是在IO單子,這是不可能簡單地執行兩次readFile
計算。這個例子(如果可能的話)如何使用綁定語法來表示?
我認爲使用Control.Monad
是沒有解決方案,因爲它在內部使用do
塊。
我認爲這有可能表達這種使用箭頭(使用&&&
) - 也許這是隻有箭頭可以作爲單子的推廣的情況下?
請注意,這個問題不是關於上面的特例,而是關於一次性計算結果在一次性表達式中使用多次的一般情況,如print
。
通常這會讓你的代碼更漂亮。'Control.Applicative'有一堆你可以用來混淆'm a'類型的東西的操作符,然後你可以把'>> ='輸出到輸出中。通常這更漂亮。有時候,免費點並不漂亮;我們可以寫'main = readFile「foo.txt」>> = flip mapM_ [(「prefix」++),(++「postfix」)]。 (打印)。翻轉身份證「,但那不會很清楚。 – AndrewC
@AndrewC感謝您的建議!在這種特殊情況下,我只關心如何轉換do語法,並且我打算保持簡單。一般來說,我完全同意你的觀點,應用是這裏的正確工具。此外,有沒有什麼具體的原因,爲什麼你不使用'forM_'而不是'flip mapM_'? –
因爲我忘了! :)讓我們假裝這是爲了避免導入'Control.Monad'的另一個原因。麻煩的是,如果你不導入Control.Monad,你會錯過可愛的(> =>):: Monad m =>(a-> mb) - >(b-> mc) - >( a - > mc)'。 – AndrewC