- 1、本文档共5页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
函数的部分应⽤和柯⾥化
上⼀章重点在于代码重复:提升现有的函数功能、或者将函数进⾏组合。这⼀章,
们来看看另外两种函数重⽤的机制:函数的部分应⽤(Partial Application of
Functions) 、 柯⾥化(Currying) 。
部分应⽤的函数
和其他遵循函数式编程范式的语⾔⼀样,Scala 允许_部分_应⽤⼀个函数。调⽤⼀个
函数时,不是把函数需要的所有参数都传递给它,⽽是仅仅传递⼀部分,其他参数留
空;这样会⽣成⼀个新的函数,其参数列表由那些被留空的参数组成。 (不要把这个
概念和偏函数混淆)
为了具体说明这⼀概念,回到上⼀章的例⼦:假想的免费邮件服务,能够让⽤户配置
筛选器,以使得满⾜特定条件的邮件显⽰在收件箱⾥,其他的被过滤掉。
Email 类看起来仍然是这样:
case class Email(
subject: String,
text: String,
sender: String,
recipient: String)
type EmailFilter = Email = Boolean
过滤邮件的条件⽤谓词 Email = Boolean 表⽰, EmailFilter 是其别名。调⽤
适当的⼯⼚⽅法可以⽣成这些谓词。
上⼀章, 们创建了两个这样的⼯⼚⽅法,它们检查邮件内容长度是否满⾜给定的最
⼤值或最⼩值。这⼀次, 们使⽤部分应⽤函数来实现这些⼯⼚⽅法,做法是,修改
size onstraint ,固定某些参数可以创建更具体的限制条件:
其修改后的代码如下:
type IntPairPred = (Int, Int) = Boolean
def size onstraint(pred: IntPairPred, n: Int, email: Email) =
pred(email.text.size, n)
上述代码为⼀个谓词函数定义了别名 IntPairPred ,该函数接受⼀对整数 (值 n 和
邮件内容长度),检查邮件长度对于 n 是否 OK 。
请注意,不像上⼀章的 size onstraint ,这⼀个并不返回新的 EmailFilter,
它只是简单的⽤参数做计算,返回⼀个布尔值。秘诀在于,你可以部分应⽤这个
size onstraint 来得到⼀个 EmailFilter 。
遵循 DRY 原则, 们先来定义常⽤的 IntPairPred 实例,这样,在调⽤
size onstraint 时,不需要重复的写相同的匿名函数,只需传递下⾯这些:
val gt: IntPairPred = _ _
val ge: IntPairPred = _ = _
val lt: IntPairPred = _ _
val le: IntPairPred = _ = _
val eq: IntPairPred = _ == _
最后,调⽤ size onstraint 函数,⽤上⾯的 IntPairPred 传⼊第⼀个参数:
val minimumSize: (Int, Email) = Boolean = size onstraint(ge,
val maximumSize: (Int, Email) = Boolean = size onstraint(le,
对所有没有传⼊值的参数,必须使⽤占位符 _ ,还需要指定这些参数的类型,这使得
函数的部分应⽤多少有些繁琐。Scala 编译器⽆法推断它们的类型,⽅法重载使编译
器不可能知道你想使⽤哪个⽅法。
不过,你可以绑定或漏掉任意个、任意位置的参数。⽐如, 们可以漏掉第⼀个值,
只传递约束值 n :
val constr20: (IntPairPred, Email) = Boolean =
size onstraint(_: IntPairPred, 20, _: Email)
val constr30: (IntPairPred, Email) = Boolean =
size onstraint(_: IntPairPred, 30, _: Email)
得到的两个函数,接受⼀个 IntPairPred 和⼀个 Email 作为参数,然后利⽤谓词
函数 IntPairPred 把邮件长度和 20 、 30 ⽐较,只不过⽐较⽅法的逻辑
IntPairPred 需要另外指定。
由此可见,虽然函
文档评论(0)