模式匹配和函数复合

这节的内容包含:

函数复合

我们首先定义两个有用的函数:

scala> def addUmm(x: String) = x + " umm"
addUmm: (x: String)String

scala>  def addAhem(x: String) = x + " ahem"
addAhem: (x: String)String

compose

compose可以通过组合其他的函数来创建一个新的函数f(g(x))

scala> val ummThenAhem = addAhem _ compose addUmm _
ummThenAhem: (String) => String = 

scala> ummThenAhem("well")
res0: String = well umm ahem

andThen

andThencompose相似,只不过它创建的函数是先调用第一个函数,然后再调用第二个,即是g(fx(x))

scala> val ahemThenUmm = addAhem _ andThen addUmm _
ahemThenUmm: (String) => String = 

scala> ahemThenUmm("well")
res1: String = well ahem umm

Currying与Partial Application

case语句

那么,case语句究竟是什么呢?

它是函数PartialFunction的一个子类。

 

那么一组case语句的集合又是什么呢?

它们是多个PartialFunction组合的结果。

理解PartialFunction

一个函数会在所有参数都是指定的类型下才能正常执行。换句话说,一个定义为(Int)=>String的函数,只能接受一个Int类型的参数,并且返回一个String类型。

一个Partial函数只能处理参数所定义类型的某些值。例如,一个Partical函数(Int)=>String不一定能接受所有的Int作为参数。

isDefinedAt是PartialFunction的一个方法,它可以用来判断这个PartialFunction是否能够接收一个指定的参数。

注意PartialFunction和我们之前讨论的部分应用函数(partial applied function)没有关系。

参考 《Effective Scala》中关于PartialFunction的观点。

scala> val one: PartialFunction[Int, String] = { case 1 => "one" }
one: PartialFunction[Int,String] = 

scala> one.isDefinedAt(1)
res0: Boolean = true

scala> one.isDefinedAt(2)
res1: Boolean = false

你可以调用一个partial函数。

scala> one(1)
res2: String = one

Partial函数可以和orElse进行组合,它可以反映出这个Partial函数对于给定的参数是否有定义。

scala> val two: PartialFunction[Int, String] = { case 2 => "two" }
two: PartialFunction[Int,String] = 

scala> val three: PartialFunction[Int, String] = { case 3 => "three" }
three: PartialFunction[Int,String] = 

scala> val wildcard: PartialFunction[Int, String] = { case _ => "something else" }
wildcard: PartialFunction[Int,String] = 

scala> val partial = one orElse two orElse three orElse wildcard
partial: PartialFunction[Int,String] = 

scala> partial(5)
res24: String = something else

scala> partial(3)
res25: String = three

scala> partial(2)
res26: String = two

scala> partial(1)
res27: String = one

scala> partial(0)
res28: String = something else

case之谜

上周我们看了一些很奇怪的用法。我们见过case语句用在函数的位置上。

scala> case class PhoneExt(name: String, ext: Int)
defined class PhoneExt

scala> val extensions = List(PhoneExt("steve", 100), PhoneExt("robey", 200))
extensions: List[PhoneExt] = List(PhoneExt(steve,100), PhoneExt(robey,200))

scala> extensions.filter { case PhoneExt(name, extension) => extension < 200 }
res0: List[PhoneExt] = List(PhoneExt(steve,100))

为什么这样是可行的呢?

filter接收一个函数作为参数。所以这里应该是一个断言函数(PhoneExt) => Boolean.

这是因为ParitalFunction是Function的子类,所以filter可以接收一个PartialFunction作为参数!

 

英文原文: Scala School,翻译:ImportNew - 朱伟杰

本文链接:http://www.importnew.com/3753.html

【如需转载,请在正文中标注并保留原文链接、译文链接和译者等信息,谢谢合作!】

关于作者: 朱伟杰

Java开发工程师,业余翻译

查看朱伟杰的更多文章 >>



相关文章

发表评论

Comment form

(*) 表示必填项

还没有评论。

跳到底部
返回顶部