盒子裏的計算
如果我們要運算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