偏函数(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 = One
scala> pf(2)
res1: String = Two
scala> pf(3)
res2: String = Three
scala> pf(4)
res3: String = Other

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

1.1 isDefinedAt

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

scala> pf.isDefinedAt(1)
res4: Boolean = true
scala> pf.isDefinedAt(2)
res5: Boolean = true
scala> 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 = true
scala> anotherPF.isDefinedAt(2)
res9: Boolean = true
scala> anotherPF.isDefinedAt(3)
res10: Boolean = true
scala> 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 = One
scala> newPF(2)
res1: String = Two
scala> newPF(3)
res2: String = Three
scala> 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 = One
scala> 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)Int
scala> def addX = add(1,_:Int,_:Int) // x 已知
addX: (Int, Int) => Int
scala> addX(2,3)
res1: Int = 6
scala> addX(3,4)
res2: Int = 8
scala> def addXAndY = add(10,100,_:Int) // x 和 y 已知
addXAndY: Int => Int
scala> addXAndY(1)
res3: Int = 111
scala> def addZ = add(_:Int,_:Int,10) // z 已知
addZ: (Int, Int) => Int
scala> addZ(1,2)
res4: Int = 13

总结

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

【Scala】Scala的偏函数和偏应用函数相关推荐

  1. Scala学习笔记(六) Scala的偏函数和偏应用函数

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

  2. Scala 偏函数和偏应用函数

    偏函数 偏函数是指仅定义了输入参数的子集的函数,如下图: 这个图显示的一个偏函数:f : X -> Y,该函数仅定义了输入参数X的子集1和3,没有包含2. 在Scala中的偏函数是通过特质Par ...

  3. Scala入门到精通——第五节 函数、高阶函数与闭包

    本节主要内容 (一)函数字面量(值函数) (二)匿名函数 (三)函数的简化 (四)函数参数 (四)闭包 函数字面量(值函数) 函数字面量(function literal),也称值函数(functio ...

  4. Scala学习之特殊符号,及函数

    http://www.runoob.com/scala/scala-functions.html scala函数的定义,注意一些特殊函数的书写 1. =>符号 var equalRight = ...

  5. Scala入门到精通——第五节 函数与闭包

    本节主要内容 (一)函数字面量(值函数) (二)匿名函数 (三)函数的简化 (四)函数参数 (四)闭包 函数字面量(值函数) 函数字面量(function literal),也称值函数(functio ...

  6. 偏函数与部分应用函数

    http://www.cnblogs.com/nixil/archive/2012/05/16/2503722.html scala中有PartialFunction的概念, 同时还要一个概念叫Par ...

  7. 大数据基础之Scala——Scala数组方法,史上最全,只要你能全部背上即可成为万人敬仰的大佬,任何Scala随便戳戳!!!

    Scala数组 数组是一种可变的.可索引的数据集合.在Scala中用Array[T]的形式来表示java中的数组形式T[ ]. //声明一个数组对象 方法一:var numbers:[String]= ...

  8. python偏函数和高阶函数_【Python入门】8.高阶函数之 匿名函数和偏函数

    目录 高阶函数 匿名函数 lambda 偏函数 高阶函数 匿名函数 lambda lambda,即希腊字母λ.顾名思义,匿名函数没有函数名,在运用时采取lambda x : ...的方式,如lambd ...

  9. Python基础-----列表生成式、偏函数、高阶函数、闭包、装饰器

    列表生成式 列表生成式(列表推导式):通俗理解使用for循环快速创建一个列表,最终要获取一个列表 下面这个我们经常使用比较麻烦的方法: my_list=[] for i in range(1,6):p ...

最新文章

  1. 基于Bootstrap Ace模板+bootstrap.addtabs.js的菜单
  2. 用setTimeout实现setInterval的功能
  3. 计算机系统化科学化和什么,自动化概论复习资料
  4. 网站架构演变和知识体系
  5. python跳回循环开始位置_如何回到python中循环的开始?
  6. 新云网、5G、Wi-Fi 6 Plus,探秘2021通信展上的锐捷网络黑科技
  7. Uber无人车安全员之困:这是一份机械、枯燥、影响心理的工作
  8. python调用sqlldr_sqlldr用法
  9. js中如何获取font标签中的内容
  10. C语言-函数(一):函数的定义和调用
  11. python爬虫学习,使用requests库来实现模拟登录4399小游戏网站。
  12. 03系统多界面_资讯:苹果公布iPhone 12屏幕更换价格;华为 Mate 40 Pro 系统界面截屏曝光;Redmi K30S 更多细节曝光...
  13. ObjectARX开发笔记(一)——分别使用AcEdInputPointFilter和AcEdInputPointMonitor实现光标提示功能
  14. ORACLE 12C EM 端口5500关闭及如何修改默认端口
  15. 财经365内参:万亿赛道迎五部门发利好
  16. 管理软件代理商的未来!
  17. 叶梓老师 数据分析与数据挖掘-培训提纲
  18. Java高级编程之常用类
  19. 2022-02-17 WPF上位机 120-三菱PLC协议之读写方法流程解析
  20. 《前任3》:谢谢和你爱过,也不遗憾错过

热门文章

  1. 【转】关于“手动重新生成注册表性能计数器”的问题
  2. codewhy_vue笔记01
  3. Idea使用Alibaba Cloud Toolkit实现一键部署项目到linux环境
  4. 【渝粤题库】国家开放大学2021春1253C语言程序设计答案
  5. Webtoos 仿Q+云桌面框架
  6. mybatis方法参数是list的批量插入
  7. 使用python将任意张图片拼接成多张大图
  8. 实战Go内存泄露【转】
  9. 织梦CMS建站系统被曝漏洞 几十万网站沦为木马网站
  10. 分数化小数计算机在线,循环小数化分数计算器