相关推荐:控制抽象之柯里化(currying)

前面说过scala允许你创建新的“感觉像是原生语言支持”的控制抽象。尽管到目前你已经看到的例子都的确是控制抽象,不过没有人会误以为他们是原生语言支持的。为了搞明白如何让控制抽象感觉更像语言的扩展,你首先需要明白称为柯里化的函

Scala基础 - 柯里化(Currying)及其应用 - 沐风 - 开源中国社区 首页 开源项目 Java 开源软件 C# 开源软件 PHP 开源软件 C/C++ 开源软件 Ruby 开源软件 Python 开源软件 Go开源软件 JS开源软件 问答 技术问答 » 技术分享 » IT大杂烩 » 职业生涯 » 站务/建议 » 支付宝专区 » 开源硬件专区 » 代码 博客 翻译 资讯 移动开发 Android开发专区 iOS开发专区 iOS代码库 Windows Phone 招聘 城市圈 当前访客身份:游客 [ 登录 | 加入开源中国 ] 当前访客身份: 游客 [ 登录 | 加入开源中国 ] 软件 代码 讨论区 新闻 博客 软件 软件 代码 讨论区 新闻 博客 joymufeng 关注 (12) 粉丝 (49) 积分 (121) Google搜索镜像https://g.jikewenku.cn/ . 发送私信 . 请教问题 博客分类 Java (4) Scala (8) Play 2.x (12) 网络技术 (3) 日常记录 (0) 阅读排行 1. 你真的了解Java中的负数? 2. PlayFramework 2.1 技巧-性能调优实战 3. Play Framework2.1源码分析 - 架构设计及线程策略分析 4. Play 2.1 - Evolution插件使用指南 5. PlayFramework 2.x 技巧-远程调试 6. Play Framework2.1源码分析 - 请求处理流程 7. PlayFramework 2.x 技巧-@ManyToMany关联 8. Play开发环境配置(play+idea+svn) 最新评论 @joymufeng :Sorry, Play-Java好久不用了,一直在用Play-Scal... 查看» @jinpeng0513 :引用来自“joymufeng”的评论试试增加db.defaul... 查看» @joymufeng :试试增加db.default.partitionCount和db.defaul... 查看» @jinpeng0513 :您好,我们公司也用play java ,我想问下,你们的... 查看» @joymufeng :引用来自“翟志军”的评论请问,如何单独执行evl... 查看» @翟志军 :请问,如何单独执行evlutions的命令,而不是pla... 查看» @joymufeng :引用来自“Sorry'”的评论您好,很幸运很高兴很激... 查看» @Sorry' :您好,很幸运很高兴很激动可以看见您的关于Play2... 查看» @Sorry' :您好,很幸运很高兴很激动可以看见您的关于Play2... 查看» @joymufeng :引用来自“西夏一品堂”的评论你好,请问playfra... 查看» 访客统计 今日访问: 18 昨日访问: 28 本周访问: 135 本月访问: 145 所有访问: 18830 空间 » 博客 » Scala Java Play 2.x 网络技术 日常记录 所有分类 原 顶 Scala基础 - 柯里化(Currying)及其应用 发表于1个月前(2016-04-04 17:00)

阅读( 34 ) | 评论( 0 ) 0 人收藏此文章, 赞 0 上海源创会5月15日与你相约【玫瑰里】,赶快来约哦~!>>>

摘要 介绍Scala中的柯里化概念及其应用。 Scala 柯里化 Currying 控制抽象 目录[-] 1. 介绍 2. Scala中柯里化的形式 3. 探究柯里化函数 4. 应用:控制抽象(Control Abstraction) 4.1 控制抽象介绍 4.2 抽象控制的实现基础 4.2.1 无参函数 4.2.2 使用{}替代() 4.2.3 传名参数(by-name parameter) 4.3 控制抽象示例 5. 参考 ### 1. 介绍 柯里化(currying, 以逻辑学家Haskell Brooks Curry的名字命名)指的是将原来接受两个参数的函数变成新的接受一个参数的函数的过程。新的函数返回一个以原有第二个参数作为参数的函数。 在Scala中方法和函数有细微的差别,通常编译器会自动完成方法到函数的转换。如果想了解Scala方法和函数的具体区别,请参考博文[Scala基础 - 函数和方法的区别](http://my.oschina.net/joymufeng/blog/652310)。 ### 2. Scala中柯里化的形式 Scala中柯里化方法的定义形式和普通方法类似,区别在于柯里化方法拥有多组参数列表,每组参数用圆括号括起来,例如: ``` def multiply(x: Int)(y: Int): Int = x * y ``` multiply方法拥有两组参数,分别是(x: Int)和(y: Int)。 multiply方法对应的柯里化函数类型是: ``` Int => Int => Int ``` 柯里化函数的类型声明是右结合的,即上面的类型等价于: ``` Int => (Int => Int) ``` 表明该函数若只接受一个Int参数,则返回一个Int => Int类型的函数,这也和柯里化的过程相吻合。 在Scala中可以直接操纵函数,但是不能直接操纵方法,所以在使用柯里化方法前,需要将其转换成类似Int,Long类型的一等公民。最简单的方式是使用编译器提供的语法糖: ``` val f = multiply _ ``` 使用Scala中的偏函数(partially applied function, 也叫部分应用函数)也可以实现转换: ``` val f = multiply(\_: Int)(\_: Int) ``` 通常在使用柯里化方法时,编译器会根据需要自动完成转换。 ### 3. 探究柯里化函数 我们仍以上面定义的multiply方法为例探索柯里化的一些细节: ``` def multiply(x: Int)(y: Int): Int = x * y ``` multiply方法对应的函数类型为(编译器会自动转换): ``` Int => Int => Int ``` 关于这个类型,上文已做过解读。 multiply(\_:Int)(\_: Int)的类型为: ``` (Int, Int) => Int ``` 上面的类型是偏函数,参数为(Int, Int), 返回值为Int. multiply(1)(\_: Int)或简写为multiply(1)_的类型为: ``` Int => Int ``` 同上,类型是偏函数,参数为(Int), 返回值为Int. multiply(1)(2)的类型为: ``` Int ``` 调用方法求值,返回Int。 ### 4. 应用:控制抽象(Control Abstraction) #### 4.1 控制抽象介绍 对于一些通用的操作可以实现成控制抽象,例如像文件打开、关闭操作。实现成控制抽象的好处是,可以在使用的时候,看起来更像是语言级别提供的功能。 #### 4.2 抽象控制的实现基础 ##### 4.2.1 无参函数 无参函数的类型是`() => T`,在使用时为了简化可以省略(),例如: ``` def runInThread(block: => Unit){ new Thread { override def run() { block } }.start() } ``` 这样定义之后,在使用的时候就可以省略() =>, ``` runInThread{ println("Hi") } ``` ##### 4.2.2 使用{}替代() 如果方法只有一个参数,则可以使用{}替代(),例如: ``` runInThread{ println("Hi") } ``` ##### 4.2.3 传名参数(by-name parameter) 与传名参数相对的是传值参数。传值参数在函数调用之前表达式会被求值,例如Int,Long等数值参数类型;传名参数在函数调用前表达式不会被求值,而是会被包裹成一个匿名函数作为函数参数传递下去,例如高阶函数的函数参数就是传名参数。 ### 4.3 控制抽象示例 withPrintWriter是一个柯里化方法,它接受两组参数,第1组参数是待操作的文件资源,第2组参数是操作文件资源的函数: ``` def withPrintWriter(file: File)(op: PrintWriter => Unit) { val writer = new PrintWriter(file) try { op(writer) } finally { writer.close() } } ``` 用法如下: ``` withPrintWriter(new File("date.txt")) { writer => writer.println(new java.util.Date) } ``` withPrintWriter确保文件资源在被使用之后一定会被关闭,并且在使用的时候,看起来更像是语言内置的关键字函数。 ### 5. 参考 1. Programming in Scala, 2nd Edition 2. 快学Scala 分享到: 0 赞 声明:OSCHINA 博客文章版权属于作者,受法律保护。未经作者同意不得转载。 « 上一篇 下一篇 » 最新热门职位 更多开发者职位上 开源中国·招聘 高级PHP架构师 哈乐沃德 月薪: 10-15K 更 后端开发工程师 更美APP 月薪: 15-30K 架构师 百米生活 月薪: 20-25K Java开发工程师(全栈工... 美餐网 月薪: 15-30K 评论 楼: ( ) 手机 Android iPhone Windows Phone 微信 发表于 删除 回复此评论 < 1 > 插入: 表情 开源软件 发表评论 插入: 表情 开源软件 关闭 插入表情 关闭 相关文章阅读 2016/04/04 Scala基础 - 函数和方法的区别 2015/01/20 参数类型推断 以及 柯里化 2014/06/10 控制抽象之柯里化(currying) 2015/07/24 JS闭包与柯里化 2013/03/27 js--反柯里化 © 开源中国(OSChina.NET) | 关于我们 | 广告联系 | @新浪微博 | 开源中国手机版 | 粤ICP备12009483号-3 开源中国手机客户端: Android iPhone WP7 开源中国社区(OSChina.net)是工信部 开源软件推进联盟 指定的官方社区

相关推荐:Scala教程12 Closure、Currying、Partially applied function

Closureclosure是指函数中包含自由变量(未在函数参数列表中指明),函数执行的结果依赖函数执行时候上下文,比如def sum(a:Int,b:Int) = a+ b + ca,b在定义函数的参数列表中,是绑定变量;z没有出现在函数的参数列表中,为自由

快照源:http://my.oschina.net/joymufeng/blog/652324