## 结论

1. 一个 Functor 就是一种实现了 Functor typeclass 的数据类型；
2. 一个 Applicative 就是一种实现了 Applicative typeclass 的数据类型；

A typeclass is a sort of interface that defines some behavior. If a type is a part of a typeclass, that means that it supports and implements the behavior the typeclass describes. A lot of people coming from OOP get confused by typeclasses because they think they are like classes in object oriented languages. Well, they’re not. You can think of them kind of as Java interfaces, only better.

## Maybe

The Maybe type encapsulates an optional value. A value of type Maybe a either contains a value of type a (represented as Just a), or it is empty (represented as Nothing). Using Maybe is a good way to deal with errors or exceptional cases without resorting to drastic measures such as error.

Maybe 类型封装了一个可选值。一个 Maybe a 类型的值要么包含一个 a 类型的值（用 Just a表示）；要么为空（用 Nothing 表示）。我们可以把 Maybe 看作一个盒子，这个盒子里面可能装着一个 a 类型的值，即 Just a ；也可能是一个空盒子，即 Nothing 。或者，你也可以把它理解成泛型，比如 Objective-C 中的 NSArray<ObjectType> 。不过，最正确的理解应该是把 Maybe 看作一个上下文，这个上下文表示某次计算可能成功也可能失败，成功时用 Just a 表示，a 为计算结果；失败时用 Nothing 表示，这就是 Maybe 类型存在的意义：

 1 data Maybe a = Nothing | Just a

 1 2 3 4 ghci> Nothing Nothing ghci> Just 2 Just 2

## Functor

 1 2 ghci> (+3) 2 5

### Functor typeclass

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

fmap 函数可类比 Swift 中的 map 方法。

### Maybe Functor

 1 2 class Functor Maybe where fmap :: (a -> b) -> Maybe a -> Maybe b

 1 2 3 instance Functor Maybe where fmap func (Just x) = Just (func x) fmap func Nothing = Nothing

 1 2 ghci> fmap (+3) (Just 2) Just 5

 1 2 ghci> fmap (+3) Nothing Nothing

## Applicative

### Applicative typeclass

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

• pure ：将一个值 a 放入上下文中；
• (<*>) ：将一个在上下文中的函数 f (a -> b) 应用到一个在上下文中的值 f a ，并返回另一个在上下文中的值 f b 。

<*> 函数的发音我也不知道，如果有同学知道的话还请告之，谢谢。

### Maybe Applicative

 1 2 3 class Functor Maybe => Applicative Maybe where pure :: a -> Maybe a (<*>) :: Maybe (a -> b) -> Maybe a -> Maybe b

 1 2 3 4 instance Applicative Maybe where pure = Just Nothing <*> _ = Nothing (Just func) <*> something = fmap func something

pure 函数的实现非常简单，直接等于 Just 即可。而对于 (<*>) 函数的实现，我们同样需要针对 Maybe 上下文的两种情况分别进行处理：当装函数的盒子为空时，直接返回一个新的空盒子；当装函数的盒子不为空时，即 Just func ，则取出 func ，使用 fmap 函数直接将 func 应用到那个在上下文中的值，这个正是我们前面说的 Functor 的功能。

 1 2 ghci> Just (+3) <*> Just 2 Just 5

 1 2 ghci> Nothing <*> Just 2 Nothing

 1 2 3 4 5 6 7 8 9 10 class Applicative m => Monad m where return :: a -> m a (>>=) :: m a -> (a -> m b) -> m b (>>) :: m a -> m b -> m b x >> y = x >>= \_ -> y fail :: String -> m a fail msg = error msg

 1 2 3 class Applicative m => Monad m where return :: a -> m a (>>=) :: m a -> (a -> m b) -> m b

>>= 函数的发音为 bind ，学习 ReactiveCocoa 的同学要注意啦。另外，>>= 函数可类比 Swift 中的 flatMap 方法。

 1 2 3 class Applicative Maybe => Monad Maybe where return :: a -> Maybe a (>>=) :: Maybe a -> (a -> Maybe b) -> Maybe b

 1 2 3 4 instance Monad Maybe where return x = Just x Nothing >>= func = Nothing Just x >>= func = func x

 1 2 3 half x = if even x then Just (x div 2) else Nothing

 1 2 3 4 5 6 ghci> Just 20 >>= half Just 10 ghci> Just 10 >>= half Just 5 ghci> Just 5 >>= half Nothing

 1 2 ghci> Just 20 >>= half >>= half >>= half Nothing

### ReactiveCocoa

RACStream 是 ReactiveCocoa 中最核心的类，它就是一个 Monad ：

 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 /// An abstract class representing any stream of values. /// /// This class represents a monad, upon which many stream-based operations can /// be built. /// /// When subclassing RACStream, only the methods in the main @interface body need /// to be overridden. @interface RACStream : NSObject /// Lifts value into the stream monad. /// /// Returns a stream containing only the given value. + (instancetype)return:(id)value; /// Lazily binds a block to the values in the receiver. /// /// This should only be used if you need to terminate the bind early, or close /// over some state. -flattenMap: is more appropriate for all other cases. /// /// block - A block returning a RACStreamBindBlock. This block will be invoked /// each time the bound stream is re-evaluated. This block must not be /// nil or return nil. /// /// Returns a new stream which represents the combined result of all lazy /// applications of block. - (instancetype)bind:(RACStreamBindBlock (^)(void))block; @end

1. + (instancetype)return:(id)value; ；
2. - (instancetype)bind:(RACStreamBindBlock (^)(void))block; 。

 1 2 3 4 5 6 /// A block which accepts a value from a RACStream and returns a new instance /// of the same stream class. /// /// Setting stop to YES will cause the bind to terminate after the returned /// value. Returning nil will result in immediate termination. typedef RACStream * (^RACStreamBindBlock)(id value, BOOL *stop);

 1 2 3 class Applicative m => Monad m where return :: a -> m a (>>=) :: m a -> (a -> m b) -> m b

 1 2 3 class Applicative RACStream => Monad RACStream where return :: a -> RACStream a (>>=) :: RACStream a -> (a -> RACStream b) -> RACStream b

 1 2 3 4 RACSignal *signal2 = [[[signal1 bind:block1] bind:block2] bind:block3];

Monad 就像是 ReactiveCocoa 中的太极，太极生两仪，两仪生四象，四象生八卦。至此，我们已经知道了 ReactiveCocoa 中最核心的原理，而更多关于 ReactiveCocoa 的内容我们将在后续的源码解析中再进行介绍，敬请期待。

## 总结

1. 一个 Functor 就是一种实现了 Functor typeclass 的数据类型；
2. 一个 Applicative 就是一种实现了 Applicative typeclass 的数据类型；

1. Applicative 是增强型的 Functor ，一种数据类型要成为 Applicative 的前提条件是它必须是 Functor ；