Scala:Function(高阶函数式编程)

Scala开篇(目录)

一个可以进行高阶函数式编程的模块,我们来看看它都实现了哪些操作,并结合源码理解一下。

  • def chain[a](fs: Seq[(a) ⇒ a]): (a) ⇒ a
    把一些列的方法串起来,挨个执行,每个方法的结果,回作为下一个方法的入参
/**定义两个函数*/
  def fun1 = (v:Int) => {
    val result = v * 10
    println(result)
    result
  }
  def fun2 = (v:Int) => {
    val result = v * 100
    println(result)
    result
  }
  //使用
    val funs = Seq(fun1,fun2)
    Function.chain[Int](funs)(2) 
  /**fun1的结果作为fun2的入参
    20
    2000
  */ 

看下chain的源代码

def chain[a](fs: Seq[a => a]): a => a = { x => (x /: fs) ((x, f) => f(x)) }

看到 /: 这个符号是不是有点眼熟,我们在Scala:Array(集合、序列)里提到过序列的操作中就有这个操作符,他会遍历序列中的元素去执行指定的操作。

  • def const[T, U](x: T)(y: U): T
    这是一个返回常量的方法,直接返回 x 值,看源码
def const[T, U](x: T)(y: U): T = x

假如我们要把一个序列中的元素替换成同一个值,我们可以使用序列的map方法

List(1, 2, 3, 4, 5).map(_=>7)

那这时我们可以用const来处理

List(1, 2, 3, 4, 5).map(Function.const(7))
/**对应源码中的x就是7,y就是List中的每个元素
如果我们按照 x+":"+y的形式打印,就是
7:1
7:2
7:3
7:4
7:5
*/
  • def tupled[a1, a2, b](f: (a1, a2) ⇒ b): ((a1, a2)) ⇒ b
    将二元函数转换为一个一元函数,参数为Tuple2类型
  def tupleFunc = (a:Int,b:Int) => {
    a+b
  }
  /**使用*/
    val funs = Function.tupled(tupleFunc)
    val v = (1,3)
    println(v.getClass.getName)
    println(funs(v))     //  4
  • def tupled[a1, a2, a3, b](f: (a1, a2, a3) ⇒ b): ((a1, a2, a3)) ⇒ b
    道理同 tupled[a1, a2, b]
  • def tupled[a1, a2, a3, a4, b](f: (a1, a2, a3, a4) ⇒ b): ((a1, a2, a3, a4)) ⇒ b
    道理同 tupled[a1, a2, b]
  • def tupled[a1, a2, a3, a4, a5, b](f: (a1, a2, a3, a4, a5) ⇒ b): ((a1, a2, a3, a4, a5)) ⇒ b
    道理同 tupled[a1, a2, b]

  • def untupled[a1, a2, b](f: ((a1, a2)) ⇒ b): (a1, a2) ⇒ b
    作用和tupled[a1, a2, b]相反

  def tupleFunc = (v:Tuple2[Int,Int]) => {
    v._1 + v._2
  }
  //转换
    val funs = Function.untupled(tupleFunc)
    println(funs(2,6)) /** 8 */
  • def untupled[a1, a2, a3, b](f: ((a1, a2, a3)) ⇒ b): (a1, a2, a3) ⇒ b
    道理同 tupled[a1, a2, b]
  • def untupled[a1, a2, a3, a4, b](f: ((a1, a2, a3, a4)) ⇒ b): (a1, a2, a3, a4) ⇒ b
    道理同 tupled[a1, a2, b]
  • def untupled[a1, a2, a3, a4, a5, b](f: ((a1, a2, a3, a4, a5)) ⇒ b): (a1, a2, a3, a4, a5) ⇒ b
    道理同 tupled[a1, a2, b]

  • def uncurried[a1, a2, b](f: (a1) ⇒ (a2) ⇒ b): (a1, a2) ⇒ b
    把一个柯里化函数转换为但 2 个参数的函数

/**声明一个柯里化函数*/
def curriedSum = (x:Int)=>(y:Int) => x + y
//转换
val funs = Function.uncurried(curriedSum)
println(funs(1,6))      // 7

源码
方法返回结果是带(a1, a2)两个参数的函数

def uncurried[a1, a2, b](f: a1 => a2 => b): (a1, a2) => b = {
    (x1, x2) => f(x1)(x2)
}
  • def uncurried[a1, a2, a3, b](f: (a1) ⇒ (a2) ⇒ (a3) ⇒ b): (a1, a2, a3) ⇒ b
    道理同 uncurried[a1, a2, b]
  • def uncurried[a1, a2, a3, a4, b](f: (a1) ⇒ (a2) ⇒ (a3) ⇒ (a4) ⇒ b): (a1, a2, a3, a4) ⇒ b
    道理同 uncurried[a1, a2, b]
  • def uncurried[a1, a2, a3, a4, a5, b](f: (a1) ⇒ (a2) ⇒ (a3) ⇒ (a4) ⇒ (a5) ⇒ b): (a1, a2, a3, a4, a5) ⇒ b
    道理同 uncurried[a1, a2, b]

  • def unlift[T, R](f: (T) ⇒ Option[R]): PartialFunction[T, R]
    将 A => Option[B] 类型的函数转换为 PartialFunction[T, R] 类型函数

  def optionFun(x : Int) = {
    println(x)
    if (x > 0) Some(x*10) else None
  }
  //使用
    val funs = Function.unlift(optionFun)
    val chars = Array(1,2,3)
    //collect需要PartialFunction类型参数
    val newchars = chars.collect(funs)
    println(newchars.mkString(","))
  /**输出为 10,20,30 */

源码(内部调用的是PartialFunction.unlifted方法)

def unlift[T, R](f: T => Option[R]): PartialFunction[T, R] = PartialFunction.unlifted(f)
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

bdmh

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值