Comonad有什麼實際用途?


Monad可以用來規範所有的上下文敏感文法(context-sensitvie grammar)語言. Comonad可以用來建立前者語言的解釋器(intepreter)或剖析器(parser)

建構上下文敏感文法的語言及其剖析器, 要是這還不夠實用, 我就不清楚啥叫實用了

簡單說, Monad建構產生語言, Comonad解構分析語言. 若Monad具體型別是m a, Comonad的具體型別是w a, 那就會存在一個函數 w a -&> m a -&> a, 此函數讓一個剖析器跟一個語言一起執行產生出 a

數學中有不少東西都具有互為對偶的結構, 對偶的結構攪和在一起會產生一個遺忘原本結構的值, 例如列向量跟行向量內積是實數, Comonad的w a跟Monad的m a一同產生a, 也是類似這麼回事

順便提我用得是Idris, 用來建一些隨機模型的EDSL


A comonad is the same thing as a monad, only backwards

比如日常中的 Reader Monad : R =&> A

其語義為 給我準備一個R,我取出A

其comonad CoReader : (A , R)

其語義為 R一開始就有,不用準備,我就能取出A (通過comonad counit/extract)

至於CoReader Comonad 咋用,可用來幹啥?這和Reader Monad 怎麼用是同一個問題...

monad 和 comonad 就是具有一定代數性質的一類數據類型而已,就comonad 來說,數據類型需要滿足其 definition (+ comonad law ),這是一種約束條件,也可叫代數性質,我們利用其代數性質去更好的構造程序,這也是函數式編程的一大特徵

所以所謂 實際應用 就是 構造程序,那麼繞不過的就是應用其代數性質,所以 如何應用=如何構造程序=如何應用其代數性質去抽象代碼

這個我怎麼會知道呢?這是程序員的事了

不過我也是個程序員,經過簡單觀察,對Comonad 還是能得出一點東西的:

counit/extract 可適用於表達 nonempty structures (nonempty list, rose tree...)

與monad 對比:A monad adds structure by consuming values. A comonad adds values by consuming structure.

以及extend 接收的coKleisli arrow 對下游計算暴露整個context特點

利用這些性質可以寫出一些工具(Lens : A =&> Store[S,B] , Zipper 等) ,一些數據結構

以及抽象某些演算法(http://blog.higher-order.com/blog/2016/04/02/a-comonad-of-graph-decompositions/)

如果我有個Monad M[A],如果我可以用M[A]構造一對伴隨函子 (M[A], W[A]) 就可以得到 Comonad W[A] (PPAP ?),所以我覺得 Comonad 是和Monad 一樣日常的東西

至於怎麼用W[A] 前面說過了,是個腦洞的問題

就說這麼多,多也說不出了,作為其它回答的補充吧

手機碼字真心累~


以語言使用的角度而言,最直接的回答是,如果Monad是一種抽象可以被用於規範/提煉一些共有行為的話,Comonad作用是一樣的。

巨個荔枝,List是不是Monad,更多的時候是有了List,然後才用Monad law去論證這個數據結構是否符合相關行為。如果符合,那麼在程序設計上,List就可以和其它Monad結合使用,使程序邏輯性更強更合理。

如果沒有Comonad的庫/語法支持,那某些符合Comonad law的數據結構就沒法提煉共性,無法與其它Comonad結構結合使用。

幾年前的paper

Should I use a Monad or a Comonad

其實就是在解答這個問題,無論是設計語言還是程序,兩者都是有相同作用力度,可是comonad在學界沒有得到足夠的重視,現有的語言也沒有很好的支持(連ek那個庫都是自己動手上……)

不是實際上用不了,而是很多時候monadic solution is good enough....

當然,如果簡單滴定義一個容器結構然後套Monad/Comonad上去做裝/解箱那就當我啥都沒說過……


或多或少覺得這能給一些對 Comonad 感興趣的跟我一樣經驗淺的讀者提供一些鏈接,希望拋磚引玉。只是兩三個鏈接,寫的很雜,因為自己理解也不多,但是感覺更佳偏實用向。

Comonad 的用途我覺得在這篇文章中這裡寫的能給一個不錯的大方向:

So here"s the deal: whenever you see large datastructures pieced
together from lots of small but similar computations there"s a good
chance that we"re dealing with a comonad.

來自《Evaluating cellular automata is comonadic》,文章內展示了如何用 Comonad 實現細胞自動機。Zipper - HaskellWiki 中提到的用於操作數據結構的 Zipper 也據說符合 Comonad Laws。這兩個用途也許能給點開導。

之後假如將 Monad 理解為命令式編程在函數式編程中的模擬裝置的話,Comonads are objects 中有提到 Comonad 可以理解為 OOP 的 Object。結尾是這麼說的:

Monads and do notation transformed the face of Haskell by
turning it into the finest imperative programming language. I believe
that comonads and method notation may similarly transform Haskell into the finest object-oriented language as well.


樓上說了挺多的了,就不展開了。

另外一般問一個typeclass有沒有用,得看有沒有有趣有用的instance,隨手翻了幾個Comonad的instance,實在無趣,更談不上有用(敝人拙見) = =


(co)monad既有也沒有實際用途。

為什麼說,(co)monad沒有實際用途。因為我們通常看到的說法就是,這裡有一個(co)monad,那裡有一個(co)monad,到處都是(co)monad,(co)monad就是好,就是好,就是好。畢竟,要是有了實際用途還怎麼能號稱avoid success at all costs。

為什麼說,(co)monad有實際用途。比如我們證明了某種計算能進行,類型要符合(co)monad,同時我們找出幾個例子,能說明他們的什麼類型能符合(co)monad。

現在問題來了,根據Curry-Howard correspondence,我們該不該把所有要證明的性質都編碼到類型里?


目前主要用於zipper


推薦閱讀:

該如何理解Monad?
學過Haskell是一種怎樣的體驗?
PureScript 是什麼?有什麼特性
精通 Haskell 是一種怎樣的體驗?
Haskell等語言中的模式匹配在C++中如何實現?

TAG:計算機科學 | 函數式編程 | Haskell | 範疇論 |