如何理解F#里的 Computation Expressions (Haskell 里的 Monads? )

為什麼我們會需要他們?為什麼不直接寫 imperative style 的code……?


1、表達邏輯是順序的但是執行不一定是,Oleg發明的Stream Monad,Iteratee Monad都是如此,使用unsafeInterleaveIO可以讓IO Monad執行也不是順序的,這樣的例子比比皆是,最著名的恐怕是JS中的非同步了。

2、其他語言所謂的順序式的代碼是所有包括了所有的副作用,程序可以做的事情不可以預測,不可以限定並且沒有條理,邏輯難以拆分,不便組合。Monad分離了各種副作用,一些Monad還有對應的Monad Transformer來組合其他的Monad,每個Monad所做的事情非常有限,邏輯拆分得非常小,基於每種Monad的操作的語義清楚,組合起他們來也是如此,如果你看了Monadic Interpreter一文,你就知道了,給你一個例子,來自於Oregon的Summer School課的代碼,這門課會寫一門Dependent typed langauge 代碼見pi-forall/Environment.hs at 2014 · sweirich/pi-forall · GitHub

type TcMonad = FreshMT (ReaderT Env (ExceptT Err IO))

TcMonad是一類型檢查Monad,它需要干3件事,異常處理、從環境中查詢類型、生成新的類型變數。分別由ExceptT、ReaderT、FreshMT這3個Monad做好,這3件事是完全分離後組合起來的!你在Java里能想像把exception這一邏輯完全分離是什麼樣子么?你沒有辦法,因為Java的異常的元語(try 、catch)是語言層面上提供的,不是庫層面的。


謝邀, LMGTFY

"Its a generic thing and it is actually a very interesting side to this in F# which is that the people sometimes look at F# Computation Expression and they say "Its Haskell monads, so its some a mechanism for monads." Its not actually just a mechanism for monads. Its also a mechanism for monoids as well, which is basically comprehensions where you might think Haskell list expressions or Python comprehensions and the like. "

Don Syme Talks About F# 2.0, a First Class Citizen in Visual Studio 2010

Why Do Monads Matter?


你可以寫imperative style的時候當然是沒有computation expression也可以完成任務的。但是有一大堆事情天生就是不用imperative style可以更早下班,譬如async io operation。


推薦閱讀:

愉悅的scheme之旅(2)--用callcc合成控制流
R語言函數式編程purrr的應用
Erlang入門教程 - 8. 在終端上輸出
編程範式與系統設計
幻想中的Haskell - Compiling Combinator

TAG:函數式編程 | Haskell | VisualF# |