Haskell 對functor和applicative的理解

盒子裏的計算

如果我們要運算1+2的話我們直接寫:1+2,這樣就會返回結果3.

但是,如果我們要計算列表裏面的數值怎麼辦呢?

例如:
我們想計算 [1] + [2],我們希望haskell能計算出的結果是[3],這時候<*>與<$>的作用就出來了,通過下面的表達式我們可以得到結果[3]

(+) <$> [1] <*> [2]

<$>會把(+)運算符變成列表內部的運算符,可以當作是一個柯里化後的函數(+) 1放入了列表變爲[ (+ 1)]

<*>就會運算列表內的計算,計算出[(+1)] 與[2]的值


1、對<$>與<*>的理解

  • 函數組合
    (.) :: (b -> c) -> (a -> b) -> a -> c

  • 0優先級的函數應用
    ($) :: (a -> b) > a -> b

  • 幫助把函數應用到函子裏的數據上
    (<$>) :: (a -> b) -> f a -> f b

  • 把函子裏的函數應用到函子裏的數據上
    (<*>) :: f (a -> b) -> f a -> f b


2、對(>>=)的理解

(>>=) :: m a -> (a -> m a) -> m b

(>>=)運算符相當於把基於applicative類型類的monad類型類m a 中的各個元素a需出來,每個元素a運用一次(a -> m b)的函數得到一系列的m b,再通過二元運算符<*>,將各個m b接連成一個新的m b

例如:

> [1,2,3,4,5] >>= \x -> [x+1]
[2,3,4,5,6]

這裏相當於將列表[1,2,3,4,5]中的各個元素1,2,3,4,5分別取出來,應用到函數(\x -> [x+1])上,分別得到[2],[3],[4],[5],[6],再通過列表的二元運算符(<*> = (++)),連接各個結果,得到最終的列表[2,3,4,5,6]


3、(-> r)的Monad實例

instance Monad (-> r) where
	(>>=) :: (r -> a) -> (a -> r -> b) -> r -> b
	f >>= g = \r -> g (f r) r

例如:

> (+1) >>= (*) >>= (-) $ 3
9

計算過程爲: (相當於(3+1)*3-3)

	(+1) >>= (*) >>= (-) $ 3
= (\r -> (*) ((+1) r) r) >>= (-) $ 3
= (\r -> (-) ((\r -> (*) ((+1) r) r) >>= (-)) r)r)  $ 3
= (-) ((*) ((+1) 3) 3) 3
= (-) ((*) 4 3) 3
= (-) 12 3
= 9
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章