【scala函数式编程】函数式数据结构

1. 定义函数式数据结构

// 定义一个临时接口,为防止被继承使用sealed进行修饰
sealed trait testList[+A]
// 定义原子实例,使得递归后可以在原子实例上进行收敛、返回结果
case object Nil extends testList[Nothing] // Nothing是代表空值的类型
// 定义组合类型,使用样例类继承接口,用于迭代生成可被拆分的组合类型
case class testCons[+A](head: A , tail:testList[A]) extends testList[A]
// 定义临时接口的实例类,对原子实例和组合类型进行递归操作
object testList{
    def sum(ints: testList[Int]):Int = ints match{
        case Nil => 0
        case testCons(x, xs) => x + sum(xs)
    }
    def product(ds: testList[Double]):Double = ds match{
        case Nil => 1.0
               // 短路逻辑:若发现有0,则直接结束递归
        case testCons(0.0, _ ) => 0.0
        case testCons(x, xs) => x * product(xs)
    }
        // 列表解析:_*只能在参数列表中使用,使得Seq[A]向下兼容A类型
    def apply[A](as:A*):testList[A] = if(as.isEmpty) Nil else testCons(as.head, apply(as.tail:_*))
}

2. 模式匹配

// 变量模式_,表示匹配任何表达式,也可以用x或y等任意变量名称代替
testList(1,2,3) match {case _ => 1} 
// 数据构造器模式,对类型进行匹配
// 通常结合变量模式_ 捕获目标的子表达式,参数个数和参数类型都必须满足要求,不能列表解析(:_*)
testList(1,2,3) match {case testCons(h, _) => h}
// 数据构造器模式,另一种形式
testList(1,2,3) match {case testCons(_, h) => h}
// 数据构造器模式,支持变长参数的匹配
List(1,2,3) match {case List(h, _*) => h}
// 数据构造器模式,错误的变长参数的匹配,_*必需放在参数列表的最后,_*为语法糖,固定搭配,不能演变为a*、b*等
List(1,2,3) match {case List(_*, h) => h}
// 数值模式,对值进行匹配
List(1,2,3) match{ case List(1,2,3) => 1}
// 若类型与数值均无法匹配,报错MatchError
List(1,2,3) match{ case Nil => 1}

3. 函数式数据结构的数据共享

理想情况下,由于函数式编程不存在副作用,可以做到:一份数据、多处引用、到处使用

4. 基于list的递归并泛化为高阶函数

<泛化>是指提取共性,降低代码重复

泛化前,观察1中定义的两个功能高度相似的sum、product的区别:
a. 参数类型差异:sum接受类型List[Int],product接受类型List[Double],泛化后应当可以处理类型List[A]
b. 递归边界条件差异:sum中List为Nil时返回0,product中List为Nil时返回1.0,泛化后应当可以指定List为空时的返回值
c. 计算方法差异:sum中计算方法为+,product中计算方法为*,泛化后应当可以指定不同的计算方法

泛化时,构思与伪代码:
a. 参数类型泛化:接受参数类型List[A]
b. 递归边界条件泛化:指定递归边界条件,兼容Int和Double类型,用B表示
c. 计算方法泛化:指定计算方法,f:(A,B) => B

泛化时,涉及的代码特性
a. 指定泛型:参数类型泛化、递归边界条件泛化、计算方法泛化时均涉及泛型,需要在方法名后标记泛型foldRight[A, B]
b. 柯里化:参数列表分为两部分,变量与函数,可以在进入sum、product方法内部后再指定函数

def foldRight[A, B](as: List[A], z: B)(f:(A, B) => B): B =
    as match {
        case Nil => z
        case testCons(x, xs) => f(x, foldRight(xs, z)(f))
    }

泛化后,新的sum、product方法

def sum2(ns:List[Int]) = foldRight(ns, 0)((x, y) => x + y)
def product2(ns:List[Double]) = foldRight(ns, 1.0)((x, y) => x * y) // (x, y) => (x * y)等价于(_ * _)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

鱼摆摆

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

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

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

打赏作者

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

抵扣说明:

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

余额充值