我只知道F#。我還沒有學習其他函數式編程語言。我所見過的單子的所有例子只描述綁定和單元方法。 F#有很多關鍵字(例如let!
,do!
等),它們允許您在同一個計算表達式中執行不同的操作。這似乎給你比你的基本綁定和單位方法更多的權力。這對於F#來說是獨一無二的,還是在函數式編程語言中很常見?F#的monad實現是否與可用關鍵字的數量相關?
回答
是的,我認爲計算表達式的F#語法是獨一無二的,因爲它爲不同類型的計算提供了直接的語法支持。它可以用於與monoids,通常monads以及還有MonadPlus來自Haskell的計算。
我寫了關於這些在my Master thesis的介紹。我相信它是非常易讀的部分,所以你可以去第27頁閱讀它。無論如何,我將在這裏複製示例:
Monoid僅用於使用某些「+」操作(Combine
)連接值。您可以使用它例如用於建築物的字符串(這是低效的,但它表明了想法):
type StringMonoid() =
member x.Combine(s1, s2) = String.Concat(s1, s2)
member x.Zero() = ""
member x.Yield(s) = s
let str = new StringMonoid()
let hello = str { yield "Hello "
yield "world!" };;
單子是使用綁定和回報comptuation表達操作熟悉的例子。例如也許單子表示計算,可以在任何點失敗:
type MaybeMonad() =
member x.Bind(m, f) =
match m with Some(v) -> f v | None -> None
member x.Return(v) = Some(v)
let maybe = new MaybeMonad()
let rec productNameByID() = maybe {
let! id = tryReadNumber()
let! prod = db.TryFindProduct(id)
return prod.Name }
添加劑單子(又名在Haskell MonadPlus
)是兩者的組合。它有點像單子計算,可以產生多個值。一個常見的例子是列表(或序列),它可以同時實現綁定和結合:
type ListMonadPlus() =
member x.Zero() = []
member x.Yield(v) = [v]
member x.Combine(a, b) = a @ b
member x.Bind(l, f) = l |> List.map f |> List.concat
let list = new ListMonadPlus()
let cities = list {
yield "York"
yield "Orleans" }
let moreCities = list {
let! n = cities
yield n
yield "New " + n }
// Creates: [ "York"; "New York"; "Orleans"; "New Orleans" ]
有一些不直接對應於任何理論概念的其他關鍵字。 use
關鍵字處理資源,for
和while
可用於實現循環。序列/列表理解實際上使用for
而不是let!
,因爲從句法的角度來看,它更有意義(並且for
通常需要一些序列 - 雖然它可能是例如異步的)。
monads根據bind
和unit
操作(僅限於)進行定義。還有其他的結構由其他操作定義(例如,在Haskell中,MonadPlus類型類具有zero
和plus
操作 - 這些對應於F#計算表達式中的Zero
和Combine
)。據我所知,F#的計算構造器在爲它們所支持的各種操作提供很好的語法方面是獨一無二的,但大多數操作都與單子無關。
結尾爲!
的F#綁定表示計算表達式,包括let! use! do! yield! return!
。
let! pat = expr in comp-expr -- binding computation
do! expr in comp-expr -- sequential computation
use! pat = expr in comp-expr -- auto cleanup computation
yield! expr -- yield computation
return! expr -- return computation
計算表達式用於「用於F#表達式語法的序列和其他非標準解釋」。這些語法形式提供了重載該語法的方式,例如,用於編碼一次性計算或單調計算,並且看起來與例如類似。 Haskell的do-notation以及該語言中的相應(非魔術)綁定形式。
所以我會說他們支持一些語法重載來支持對語言表達式語法的其他解釋,而這與他們與許多語言(包括Haskell和OCaml)都有相同之處。這當然是一個強大且有用的語言功能。
(從內存中調出,我可能會關閉。)
雖然我認爲unit
和bind
是單子典型的基礎上,我想也許map
和join
爲基礎不同,我在學術論文見過。這有點像LINQ如何在C#和VB中工作,其中各種from
語法解析爲Select
或SelectMany
,它們與map
和join
相似。 LINQ也有一些額外的關鍵字,有點像F#,雖然更特別(並且最適合查詢枚舉/數據庫)。我不知道像F#這樣的其他函數式語言如何將大部分控制流和其他語法有效地「提升」爲monad(以及「計算表達式」,其中可能是monads),但是我不知道。
對於它的價值,「規範」的基礎將是地圖,單元和連接的全部三個;所有都是獨特和正交的,結果在數學上令人愉快。 「bind」操作是一個複合map +連接,只存在是因爲它在概念上更方便用monad編程 - 在LINQ的情況下,想象只用'Select'和'Concat'而不是'SelectMany'做所有事情。 – 2011-05-17 22:19:04
- 1. F#:實現接口與函數名稱相同的關鍵字開始
- 2. Java中是否有任何關鍵字與C#中的'AS'關鍵字相似?
- 3. 可用的編譯器是否提供了C11'_Atomic'關鍵字及其相關頭文件'stdatomic.h'的實現?
- 4. Hadoop reduce函數的輸入是否與關鍵字完整相關?
- 5. 動態關鍵字啓用「也許」monad?
- 6. std :: async - 與實現相關的用法?
- 7. C99'restrict'關鍵字的現實用法?
- 8. f#關鍵字的使用和使用
- 9. MPLab中的inline關鍵字是否相關?
- 10. Apache Solr實現多字的關鍵字
- 11. '是'VB.NET關鍵字與Object.ReferenceEquals相同嗎?
- 12. 是否可以將POCO實體與標準實體相關聯?
- 13. F#:關鍵字時總是「意外」
- 14. F# - 什麼是「it」關鍵字?
- 15. 是否可以關閉'svn export'的關鍵字替換?
- 16. 是否可以使用`retry`關鍵字與`if`內聯?
- 17. 是否有可能將「關鍵字」也視爲「非關鍵字」的語法?
- 18. read_excel的chunksize關鍵字未實現
- 19. 實現對相關數據
- 20. XHTML ...是否與此相關?
- 21. 是否有可能通過函數使用關鍵字參數
- 22. cscope基本關鍵行爲 - 是否可以配置? (不與vim相關)
- 23. F#中有沒有C#的@關鍵字?
- 24. 打印與字典值相關的關鍵字
- 25. Markup monad如何與Html monad關聯?
- 26. 使用關鍵字在F#標識符
- 27. F#是否與Haskell相當?
- 28. 是否可以使用查詢參數填充IN關鍵字
- 29. 在robotframework中是否可以將關鍵字傳遞給變量?
- 30. ViewData字典中的數據是否與Model序列化相關?
托馬斯,上面的文件鏈接不再工作。這裏是新的鏈接,http://tomasp.net/academic/theses/events/events.pdf。 – kimsk 2014-12-15 08:10:42