swift实例解析Functor,Monad,Applicati

作者: 微微笑的蜗牛 | 来源:发表于2015-12-01 11:50 被阅读190次

    之前在网上看到几篇文章,但是一直都没看懂,直到看Argo的源码时,发现它里面也定义了这些,只不过是用Enum的,明白了许多。有兴趣的可以看看。

    Functor,Monad,Applicative都是指一种数据类型,只要该类型实现了其规定的方法,就可称为Functor/Monad/Applicative。

    Functor

    haskell中的定义:

    class Functor f where 
        fmap :: (a -> b) -> f a -> f b 
    

    实现了 (a -> b) -> f a -> f b的类型称为Functor,f表示一种类型
    假定将(a->b)叫function,fa是指在上下文中的值,好比a装在箱子里Box(a)包起来了。可以用这样一个结构表示上下文。

    //*************************************
    // 均以Box为上下文
    //*************************************
    struct Box<T> {
        private var value: T
        init(_ value: T) {
            self.value = value
        }
    
        func unbox() -> T {
            return self.value
        }
    }
    
    // 实现了 (a -> b) -> f a -> f b的类型称为Functor,f表示一种类型
    // ((a->b), Box(a)) -> Box(b)
    // 表示函数第一个参数(a, b)是个函数f,第二个参数是fa(有上下文,这里指Box,取出a,需要unbox)
    // 1.a = unbox a
    // 2.b = f(a)
    // 3.Box(b)
    infix operator <^> { associativity left }
    func <^><T, U>(f: T -> U, x: Box<T>) -> Box<U> {
        return x.map(f)
    }
    
    // 此时Box是个Functor
    extension Box {
        func map<U>(f: T -> U) -> Box<U> {
            return Box<U>(f(unbox()))
        }
    }
    

    下图是比较形象的图片表示,(+3)就相当于我们定义的函数f,Box(2)是在上下文中的值。取出2,进行+3,然后再包装成Box。


    Functor图片表示

    Applicative

    haskell中的定义:

    class (Functor f) => Applicative f where     
        pure :: a -> f a     
        (<*>) :: f (a -> b) -> f a -> f b 
    

    实现了 f(a -> b) -> f a -> f b, a -> f a的的类型称为Applicative。
    f(a -> b)指在上下文中的函数,用Box可以表示为:Box<A->B>
    fa值在上下文中的值,Box(a)

    // (Box(a->b), Box(a)) -> Box(b)
    // 1.f = unbox function
    // 2.a = unbox a
    // 3.调用f(a)返回b,b=f(a)
    // 4.Box(b)
    infix operator <*> { associativity left }
    
    func <*><T, U>(f: Box<T -> U>, x: Box<T>) -> Box<U> {
        return x.apply(f)
    }
    
    // a->Box(a)
    func pure<T>(x: T) -> Box<T> {
        return Box(x)
    }
    
    // 此时Box是个Applicative
    extension Box {
        func apply<U>(f: Box<T -> U>) -> Box<U> {
            let function = f.unbox()
    
            return map(function)
        }
    }
    

    图片解说:
    function,2均在Box中,需要取出,进行运算后,再放入Box


    Applicative图片表示

    Monad

    haskell中的定义:

    class Monad m where 
        return :: a -> m a  
        (>>=) :: m a -> (a -> m b) -> m b 
        ...
    

    实现了 m a -> (a -> m b) -> m b的类型称为Monad
    m a指上下文中的值,Box(a)
    (a -> m b)是一个函数,非上下文。传入a,返回Box(b)

    // (Box(a), (a->Box(b))) -> Box(b)
    // 表示第一个参数是在上下文中,函数(a, mb) 输入unbox的a值,输出Box
    // 1.a = unbox a
    // 2.Box(b) = f(a)
    infix operator >>= { associativity left }
    func >>=<T, U>(x: Box<T>, f: T -> Box<U>) -> Box<U> {
        return x.flatMap(f)
    }
    
    // 此时Box是个Monad
    extension Box {
        func flatMap<U>(f: T -> Box<U>) -> Box<U> {
            let value = unbox()
            return f(value)
        }
    }
    
    Monad图片表示

    测试代码

    // Functor Test
    let box1 = Box<Int>(2)
    
    // add 2
    let function1: (Int -> String) = { x in
        return String(x + 2)
    }
    
    let r1 = function1 <^> box1
    print(r1.unbox())
    
    // Monad Test
    let box2 = Box<Int>(3)
    let function2: (Int -> Box<Int>) = { x in
        return Box<Int>((x + 2))
    }
    
    let r2 = box2 >>= function2
    print(r2.unbox())
    
    // Applicative Test
    let box3 = Box<Int>(4)
    let function3: Box<Int -> Int> = Box<Int -> Int>({ x in
        return x + 2
    })
    
    let r3 = function3 <*> box3
    print(r3.unbox())
    

    相关文章

      网友评论

        本文标题:swift实例解析Functor,Monad,Applicati

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