1.Functor, Applicative, 和Monad,?都是deal with有context的值的類型(typeclass), 就像一個包裹著禮物的盒子.?
比較經(jīng)典是三個例子是Maybe, List, 和Function, 他們既是Functor, 也是Applicative,也是Monad:
Maybe 的context代表值是否存在
[], 也就是List 的context代表非確定性
(->) r, 也就是接受返回值類型的類型構(gòu)造器生闲,他的context是傳入值妨马。
2. 他們有不同的方法
class Functor f where
? ? fmap::(a->b) -> f a -> f b
這里的f不是具體類型书释,而是一個取一個類型參數(shù)的類型構(gòu)造器
比如Maybe Int是一個具體類型寒匙,而Mabybe是一個取一個類型參數(shù)的類型構(gòu)造器。
類似的,[]對應(yīng)[Int], ? (->) r 對應(yīng) (->) r a.
class (Functor f) ?=> Applicative f where
? ? pure :: a -> f a
? ? (<*>) :: f (a -> b) -> f a -> f b
可以看到Applicative和Functor關(guān)聯(lián)性很大。第一行開始Applicative類的定義,同時引入了一個約束類泽铛。這個類約束說:如果我們想把某個類型構(gòu)造器變成Applicative類型類的實例,它必然先成為Functor的實例钳降。
class Monad m where?
? ? return :: a -> m a
? ? (>>=) :: m a -> (a -> m b) -> m b
最經(jīng)典的幾個例子都是: Maybe, List, Function
List:
Functor
instance Functor [] where
? ? fmap = map
Applicative
instance Applicative [] where
? ? pure x = [x]
? ? fs <*> xs = [f x | f <- fx, x <- xs]?
example:?
ghci>[(*0),(+100),(^2)]<*>[1,2,3]
[0,0,0,101,102,103,1,4,9]
Left-associative:
ghci>[(+),(*)]<*>[1,2]<*>[3,4]
[4,5,5,6,3,4,6,8]
Monad
instance Monad [] where?
? ? return x = [x]
? ? xs >>= f = concat (map f xs)
example:
ghci>[3,4,5]>>=\x->[x,-x]
[3,-3,4,-4,5,-5]
Function:
Functor:
instance Functor ((->) r) where
? ? fmap f g = (\x -> f (g x))
根據(jù)fmap的類型: ??
fmap :: (a -> b) -> f a -> f b
把f替換成(->) r: ??
?( a -> b ) -> ( (->) r a ) -> ( (->) r b )
寫成中綴形式: ? ?
?( a -> b ) -> ( r -> a ) -> ( r -> b )
那么很明顯, 把函數(shù)( r -> a )和( a- > b)組合起來厚宰,就得到函數(shù)( r-> b)
所以說定義這個實例的另外一種方法是:
instance Functor ( (->) r) where
? ? fmap = (.)
Applicative:
instance Applicative ((->) r) where
? ? pure x = (\_ -> x)
? ? f <*> g = \x -> f x (g x)
(<*>) :: f (a -> b) -> f a -> f b
funny thing here: f (a -> b) 把 (->) r帶入f, 意思是傳入類型為r的參數(shù),返回(a->b)類型的函數(shù)遂填,那么容易理解 :
f <*> g = \x -> f x (g x)
例子
ghci>:t (+)<$>(+3)<*>(*100)
(+)<$>(+3)<*>(*100)::(Numa)=>a->a
ghci>(+)<$>(+3)<*>(*100)$5
508
ghci>(\x y z->[x,y,z])<$>(+3)<*>(*2)<*>(/2)$5
[8.0,10.0,2.5]
Monad:
instance Monad ((->) r) where
? ? return x = \_ -> x
? ? h >>= f = \w -> f (h w) w
Monad最經(jīng)典的用法是鏈?zhǔn)剑?/p>
foo :: Maybe String
foo = Just 3 >>= (\x -> Just "!" >>= (\y -> Just (show x ++ y)))
結(jié)果 Just "3!"
分行寫:
foo = Just 3 >>= (\x ->
Just "!" >>= (\y ->
Just (show x ++ y)))
用do記法:
foo = do
x <- Just 3
y <- Just "!"
Just (show x ++ y)