- 1、本文档共11页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
Swift演示Functors, Applicatives, and Monads 最近学习RAC的了解到其核心思想FRP即函数响应式编程,来学习一下什么是函数式编程。 以前一直行令式编程,即一行一行的代码拼凑起来完成程序的各个状态。函数式编程,从名字看就是用一个个函数来编程,就是用函数来改变程序的各个状态。我的简单理解就是一个盒子封装了一个值,这个盒子通过自身的一个方法可以运用一个同样被封装在盒子里的方法,并返回一个盒子封装了运行结果的值。这个值可以继续运用方法返回一个带有新值的盒子,这样一个函数一个函数继续调用。 下面用图片和Swift演示这三者。 Functors 我们知道一个方法如何应用到一个值上,但如何这个值被封装在一个盒子里面就无法应用到值上: 这就是map函数的由来,map函数定义方法如何应用到值上。任何定义了map的类型都是Functor,map内部实现如下: 盒子可以认为就是Optional类型,Optional是对值的一种封装,它把值和空放到了一个枚举(enum)类型中。所以可以这样做: Optional.Some(2).map { $0 + 3 } // = .Some(5) map函数让方法+3应用到了2值上,因为Optional是一个Functor,它表明了map是如何应用.Some和.None。 func map(f: T - U) - U? { switch self { case .Some(let x): return f(x) case .None: return .None } 如果Optional有值,就把值取出来应用到函数上,运行结果放到的Option类型中返回。 如果没有值就返回没有值即值为None的Optional类型。 如果没有Optional类型,我们就会写很多if else来判断值的有无。而为空的时候直接就返回.None了,比以前方便多了。 同理array和函数也有map方法所以它们也是Functor,array应用一个方法还是得到一个array,函数应用一个方法还是得到一个函数。 Applicatives Applicate再提高一层,把方法也放到盒子中。 Swift 还并没有内置处理 Applicative 的方法。但是添加一个非常简单,我们可以定义一个apply函数来支持各种类型,从而支持Applicative,它定义如何将一个盒子中的函数作用于盒子中的值: extension Optional { func apply(f: (T - U)?) - U? { switch f { case .Some(let someF): return self.map(someF) case .None: return .None } } } 如果值和函数都是.Some,函数将被应用于解包的值上。如果为.None就返回.None。注意因为optional类型是被定义为Optional我们只需要在apply声明处声明泛型 U 我们也可以定义*,做同样的使用 infix operator * { associativity left } func *T, U(f: (T - U)?, a: T?) - U? { return a.apply(f) } Optional.Some({ $0 + 3 }) * Optional.Some(2) //Optional(5) print(xxxxx : ,Optional.Some({ $0 + 3 }) * Optional.Some(2)) 2和(+3)方法从盒子取出后,把(+3)方法应用到2值上,运行的结果2再放到一个新的盒子中。 Monads Functor 应用一个方法到一个包装的值上: Applicatives 应用一个包装的函数到一个包装的值上: Monads 应用一个返回包装值的函数到一个包装的值上。 Monads有个函数flatMap能处理这个。定义操作符- infix operator - { associativity left } func -T, U(a: T?, f: T - U?) - U? { return a.flatMap(f) } 假定half是一个函数,只能处理基本数值类型: func half(a: Int) - Int? { return a % 2 == 0 ? a / 2 : .None } 但让它处理包装过的值呢?它无法处理,因为他的如参是一个值: 这时候需要使用-方法,它可以取出值放到函数中运行,Optional就是强制拆包。 这里看它是如何工作的: Optional(3)
文档评论(0)