Scala 系列 - 函数

本文主要对 函数式编程语言 与 Scala 中的函数进行介绍

函数式编程语言

严格意义上来讲,一门函数式编程语言不需要有可变类型的变量,赋值操作,或者是循环等控制结构。

广义上来说,函数式编程语言可以关注于函数,写出优雅的代码。

在我们学习 Scala 的时候,相信大家都看过一句话,在函数式编程语言中,函数是一等公民。那么这句话是什么意思呢?

  • 函数可以在任何地方被定义,甚至在其他函数内部
  • 函数可以被当成函数的参数传递于函数的返回值返回
  • 有一系列操作符可以把函数组合成其他函数

下面对 Scala 中的函数进行介绍

匿名函数

在 Scala 中不需要给每一个函数命名,就像是不需要给每一个数字命名一样。

和 Python 中的 lambda 表达式有些相似

// 匿名函数 把传入的参数乘3
(X : Int) => 3 * X
// 可以赋值给某个变量
val func = (x: Int) => 3*x
val a = Array(1,2,3)
// 以下三种写法等价 将a中的每个元素乘3
a.map(func)
a.map((x: Int) => 3*x)
// 不加句点的写法更加常见一些
a map(func)
# 对应的Python代码
list(map(lambda x:3*x, [1,2,3]))

函数做为函数的参数与返回值

// 函数做为参数
(f: (Double)=>Double) => f(3)

// 函数做为返回值
(x: Int) => ((n: Double)=>x*n)

参数(类型)推断

def func0(f: (Double) => Double) = f(3)
// 得到结果0.75
func0((x: Double) => 0.25 * x)
// 因为 func0 知道传入的函数类型,所以可以省略x的类型,简化为
func0((x) => 0.25 * x)
// 更进一步
func0(x => 0.25 * x)
// 再进一步 因为参数只在 => 右边出现了一次
func0(0.25 * _)

注意,以上所有的简写,都要在能够推断出类型的前提下

一些常用的高阶函数

val a = Array(1,2,3,4,5)
a.map(_ * 2)
a.filter(_ % 2==0)
a.reduceLeft(_ * _)
# 等价于Python中
a = [1,2,3,4,5]
list(map(lambda x: x*2, a))
list(filter(lambda x: x%2 == 0, a))
from functools import reduce
reduce(lambda x, y: x*y, a)

柯里化

指将原来接收两个参数的函数变成新的接受一个参数的函数的过程,新的函数返回一个以原有第二个参数作为参数的函数。

比如def mul(x: Int, y: Int)=x*y转变成def newmul(x: Int)=(y: Int) => x*y

例如,对[a, b]区间内的数,求进行f运算后的乘积,

def sum(f: Int => Int, a: Int, b: Int) : Int ={
    if (a>b) 1
    else f(a)*sum(f, a+1, b)
}

可以柯里化成如下表示,

def sum(f: Int => Int): (Int, Int)=>Int ={
    def tmp(a: Int, b: Int): Int ={
        if (a>b) 1
        else f(a)*tmp(a+1, b)
    }
    tmp
}

等价于

def sum(f: Int => Int)(a: Int, b: Int) : Int ={
    if (a==b) 1
    else f(a)*sum(f)(a+1, b)
}

参考资料:《Functional Programming Principles in Scala》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值