美文网首页
Functor, Applicative, and Monad

Functor, Applicative, and Monad

作者: tigerhy1 | 来源:发表于2015-08-21 12:05 被阅读0次

    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

          本文链接:https://www.haomeiwen.com/subject/nxegqttx.html