1. 偏函数

偏函数(Partial Function),是一个数学概念它不是"函数"的一种, 它跟函数是平行的概念。
Scala中的Partia Function是一个Trait,其的类型为PartialFunction[A,B],其中接收一个类型为A的参数,返回一个类型为B的结果。

举个例子


scala> val pf:PartialFunction[Int,String] = {|   case 1=>"One"|   case 2=>"Two"|   case 3=>"Three"|   case _=>"Other"| }
pf: PartialFunction[Int,String] = <function1>scala> pf(1)
res0: String = Onescala> pf(2)
res1: String = Twoscala> pf(3)
res2: String = Threescala> pf(4)
res3: String = Other

偏函数内部有一些方法,比如isDefinedAt、OrElse、 andThen、applyOrElse等等。

1.1 isDefinedAt

isDefinedAt : 这个函数的作用是判断传入来的参数是否在这个偏函数所处理的范围内。
刚才定义的pf来尝试使用isDefinedAt(),只要是数字都是正确的,因为有case _=>"Other"这一句。如果换成其他类型就会报错。

scala> pf.isDefinedAt(1)
res4: Boolean = truescala> pf.isDefinedAt(2)
res5: Boolean = truescala> pf.isDefinedAt("1")
<console>:13: error: type mismatch;found   : String("1")required: Intpf.isDefinedAt("1")^scala> pf.isDefinedAt(100)
res7: Boolean = true

那我们再定义一个PartialFunction

scala> val anotherPF:PartialFunction[Int,String] = {|    case 1=>"One"|    case 2=>"Two"|    case 3=>"Three"| }
anotherPF: PartialFunction[Int,String] = <function1>scala> anotherPF.isDefinedAt(1)
res8: Boolean = truescala> anotherPF.isDefinedAt(2)
res9: Boolean = truescala> anotherPF.isDefinedAt(3)
res10: Boolean = truescala> anotherPF.isDefinedAt(4)
res11: Boolean = false

去掉了原先的最后一句,再执行anotherPF.isDefinedAt(4)会返回false。

1.2 orElse

orElse : 将多个偏函数组合起来使用,效果类似case语句。


scala> val onePF:PartialFunction[Int,String] = {|   case 1=>"One"| }
onePF: PartialFunction[Int,String] = <function1>scala> val twoPF:PartialFunction[Int,String] = {|   case 2=>"Two"| }
twoPF: PartialFunction[Int,String] = <function1>scala> val threePF:PartialFunction[Int,String] = {|   case 3=>"Three"| }
threePF: PartialFunction[Int,String] = <function1>scala> val otherPF:PartialFunction[Int,String] = {|   case _=>"Other"| }
otherPF: PartialFunction[Int,String] = <function1>scala> val newPF = onePF orElse twoPF orElse threePF orElse otherPF
newPF: PartialFunction[Int,String] = <function1>scala> newPF(1)
res0: String = Onescala> newPF(2)
res1: String = Twoscala> newPF(3)
res2: String = Threescala> newPF(4)
res3: String = Other

这样,newPF跟原先的pf效果是一样的。

1.3 andThen

andThen: 相当于方法的连续调用,比如g(f(x))。

scala> val pf1:PartialFunction[Int,String] = {|   case i if i == 1 => "One"| }
pf1: PartialFunction[Int,String] = <function1>scala> val pf2:PartialFunction[String,String] = {|   case str if str eq "One" => "The num is 1"| }
pf2: PartialFunction[String,String] = <function1>scala> val num = pf1 andThen pf2
num: PartialFunction[Int,String] = <function1>scala> num(1)
res4: String = The num is 1

pf1的结果返回类型必须和pf2的参数传入类型必须一致,否则会报错。

1.4 applyOrElse

applyOrElse:它接收2个参数,第一个是调用的参数,第二个是个回调函数。如果第一个调用的参数匹配,返回匹配的值,否则调用回调函数。

scala> onePF.applyOrElse(1,{num:Int=>"two"})
res5: String = Onescala> onePF.applyOrElse(2,{num:Int=>"two"})
res6: String = two

在这个例子中,第一次onePF匹配了1成功则返回的是"One"字符串。第二次onePF匹配2失败则触发回调函数,返回的是"Two"字符串。

2. 偏应用函数

偏应用函数(Partial Applied Function)也叫部分应用函数,跟偏函数(Partial Function)从英文名来看只有一字之差,但他们二者之间却有天壤之别。

部分应用函数, 是指一个函数有n个参数, 而我们为其提供少于n个参数, 那就得到了一个部分应用函数。
个人理解的偏应用函数类似于柯里化,可以参考我以前写的文章借助Java 8实现柯里化

举个例子,定义好一个函数有3个参数,再提供几个有1-2个已知参数的偏应用函数

scala> def add(x:Int,y:Int,z:Int) = x+y+z
add: (x: Int, y: Int, z: Int)Intscala> def addX = add(1,_:Int,_:Int) // x 已知
addX: (Int, Int) => Intscala> addX(2,3)
res1: Int = 6scala> addX(3,4)
res2: Int = 8scala> def addXAndY = add(10,100,_:Int) // x 和 y 已知
addXAndY: Int => Intscala> addXAndY(1)
res3: Int = 111scala> def addZ = add(_:Int,_:Int,10) // z 已知
addZ: (Int, Int) => Intscala> addZ(1,2)
res4: Int = 13

总结

本篇笔记是为了下一篇 Scala 模式匹配所做的铺垫。模式匹配会用到偏函数,所以先整理出来。还详细介绍了偏函数和偏应用函数的区别。

作者:fengzhizi715
链接:https://www.jianshu.com/p/0a8a15dbb348
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

Scala学习笔记(六) Scala的偏函数和偏应用函数相关推荐

  1. scala 学习笔记(scala for the impatient)

    scala 融合了面相对编程和面向对象编程的思想,现在java8出世了,其中的lambda表达式和scala的语法很相似,估计面向函数编程会成为一种趋势. 通过这段时间的学习,最大的感觉就是scala ...

  2. Scala学习笔记(三)

    Scala学习笔记(三) 一.模式匹配 1. 简单模式匹配 2. 匹配类型 3. 守卫 4. 匹配样例类 5. 匹配数组 6. 匹配列表 7. 匹配元组 8. 变量声明中的模式匹配 8.1 获取数组中 ...

  3. Spark学习笔记[1]-scala环境安装与基本语法

    Spark学习笔记[1]-scala环境安装与基本语法   正所谓工欲善其事必先利其器,Spark的开发语言不是java而是scala,虽然都是运行于JVM,但是两门语言的基本特性还是有些不一样,这里 ...

  4. Scala学习笔记(一)

    Scala学习笔记(一) 一.Scala简介 二.Scala安装与配置 1. 安装JDK 2. 安装Scala SDK 3. 安装IDEA插件 三.Scala解释器 1. 启动Scala解释器 2. ...

  5. Scala 学习笔记

    Scala 学习笔记 1 object func_exp { 2 println("Welcome to the Scala worksheet") //> Welcome ...

  6. Scala学习笔记04:内建控制结构

    Scala学习笔记04:内建控制结构 scala提供的控制结构并不算多,因为在函数式编程中,可以自己开发出各种功能的控制结构,所以scala提供的原生控制结构仅仅够用为止. 1.if - 判断 if是 ...

  7. Scala学习笔记03:操作符

    Scala学习笔记03:操作符 一.scala中操作符与方法的等价性 scala中操作符即方法.方法即操作符.scala中操作符其实是普通方法调用的另一种表现形式,运算符的使用其实就是隐含地调用对应的 ...

  8. Scala学习笔记02:数据类型、常量与变量

    Scala学习笔记02:数据类型.常量与变量 一.数据类型 1.基本数据类型 Byte 字节型 Short 短整型 Int 整型 Long 长整型 Char 字符型 String 字符串 Float ...

  9. 【Scala】Scala的偏函数和偏应用函数

    偏函数(Partial Function),是一个数学概念它不是"函数"的一种, 它跟函数是平行的概念. Scala中的Partia Function是一个Trait,其的类型为P ...

最新文章

  1. LeetCode简单题之三角形的最大周长
  2. Numpy 对象和字符串相互转换
  3. Struts2的概述和入门
  4. 华为,15万大军孤独行走在世界上
  5. 背景图片适应屏幕百分百
  6. accp8.0转换教材第6章连接MySQL理解与练习
  7. 官网下载InstallShield Limited Edition for Visual Studio
  8. R语言 rgl plot3d函数
  9. c盘减肥//请在阅读本文之前查看你C盘的可用空间
  10. Java实现Socket网络聊天室
  11. win7计算机双击变管理,如何修复Win7系统鼠标单击以双击
  12. mysql查询语句ppt_mysql简单查询.ppt
  13. 国家互联网信息办公室修订《互联网跟帖评论服务管理规定》发布施行
  14. 哥特巴赫猜想 尾递归 湘潭孕妇之后的自我检讨
  15. 2022哈工大软件构造lab1小结(知识点)
  16. Constraint generation(CG) approach
  17. JavaScript的精华与糟粕
  18. shtml学习笔记 SSI 指令 语法 详细说明
  19. 常见链表面试题(下)
  20. 道路积水监测、城市道路积水监测系统、路面积水监测系统—西北某省会城市案例分享

热门文章

  1. html flex布局换行,如何用css的flex布局实现换行呢?
  2. matlab全局阈值ostu,Otsu的全局阈值处理实现
  3. flink-DataStream-Source(超级详细)
  4. 中央电大网考计算机基础试题,电大网考计算机应用基础统考试题
  5. ## 从虚拟机栈的角度看i++和++i
  6. 使用 F12 开发人员工具
  7. Linux下tar命令解压到指定的目录
  8. 携手同行,共赴未来......
  9. 洞见科技数据科学家王湾湾:隐私计算助推金融业数字化转型
  10. 利用Windows的命令行工具tasklist和findstr,start结合计划任务