2015年11月23日 星期一

Functors,applicatives,and monads notes(I)

http://adit.io/posts/2013-04-17-functors,_applicatives,_and_monads_in_pictures.html
比from great of good更多的圖片說明,有舉其他語言的例子來解釋為什麼需要這些元素。

筆記
functor用來做條件選擇的function很酷!
有些function也能當作functor來用! (fmap (+3) (+2)) 帶出下一個applicative
前面提到functor感覺是把單純的value用context裝起來,context就是所謂的functor。如果context裡面裝的不是value而是function時,就變成applicative。

functor用來包value applicative用來包function來和funcotr對接,monad(>>=)用來把包好的value塞到function裡,他舉的half例子是吃一般value轉成包好的,如果一開始就傳包好的(如Just 4)該怎麼辦?monad就是拿來處理此狀況(?)
Maybe是三位一體阿! 符合上面三個「東西」的條件。
以(>>=)的datatype來看:(>>=) :: Monad m => m a -> (a -> m b) -> m b
他吃兩個東西:我們想算的,已經用m包好的數值a,原本只吃數值a,吐運算完用m包好的b的function。最後吐出算好用m包好的b。
順帶一提:>>=是中置運算。

IO居然也是monad!!!
getLine吃user輸入,包成IO String
readFile吃String,傳回文件內容(包成IO String)
putStrLn吃String,傳到螢幕上(IO ())
用>>=把大家串起來:getLine >>= readFile >>= putStrLn
可以輸入一段String(檔名),getLine把他包成IO String餵給readFile,readFile根據檔名把檔案內容抓出來包成IO String,最後給putStrLn輸出到螢幕上。 記住每個函數其實都是吃String,是我們用了>>=讓他們也可以接受IO (String)的格式。

有講一個do的文法糖,範例如下:
foo = do filename <- getLine contents <- readFile filename putStrLn contents
<-似乎在do block裡面有其效果?

看完才發現有中文版orz 不過是簡體字
還有Python版

待釐清:instance?
different between <$> and <*>:就是applicatives和functor的文法糖

小結:舉例詳盡的網站,但抽象的概念不可能用實際例子去完全窮舉,還是得從定義下手做苦工才行。