Functor, Applicative, and Monad

1.Functor, Applicative, 和Monad, 都是deal with有context的值的类型(typeclass), 就像一个包裹着礼物的盒子. 

比较经典是三个例子是Maybe, List, 和Function, 他们既是Functor, 也是Applicative,也是Monad:

Maybe 的context代表值是否存在

[], 也就是List 的context代表非确定性

(->) r, 也就是接受返回值类型的类型构造器,他的context是传入值。


2. 他们有不同的方法

class Functor f where

    fmap::(a->b) -> f a -> f b

这里的f不是具体类型,而是一个取一个类型参数的类型构造器

比如Maybe Int是一个具体类型,而Mabybe是一个取一个类型参数的类型构造器。

类似的,[]对应[Int],   (->) r 对应 (->) r a.


class (Functor f)  => Applicative f where

    pure :: a -> f a

    (<*>) :: f (a -> b) -> f a -> f b

可以看到Applicative和Functor关联性很大。第一行开始Applicative类的定义,同时引入了一个约束类。这个类约束说:如果我们想把某个类型构造器变成Applicative类型类的实例,它必然先成为Functor的实例。


class Monad m where 

    return :: a -> m a

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


最经典的几个例子都是: 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))


根据fmap的类型:   

fmap :: (a -> b) -> f a -> f b

把f替换成(->) r:   

 ( a -> b ) -> ( (->) r a ) -> ( (->) r b )

写成中缀形式:    

 ( a -> b ) -> ( r -> a ) -> ( r -> b )

那么很明显, 把函数( r -> a )和( a- > b)组合起来,就得到函数( 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的参数,返回(a->b)类型的函数,那么容易理解 :

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最经典的用法是链式:

foo :: Maybe String

foo = Just 3 >>= (\x -> Just "!" >>= (\y -> Just (show x ++ y)))

结果 Just "3!"

分行写:

foo = Just 3 >>= (\x ->

Just "!" >>= (\y ->

Just (show x ++ y)))

用do记法:

foo = do

x <- Just 3

y <- Just "!"

Just (show x ++ y)

你可能感兴趣的:(Functor, Applicative, and Monad)