使用Scala对带状态函数或API进行抽象的示例(State)

Scala Traits 实战:线性化、混入与生产级横切抽象 Scala Traits 是融合面向对象与函数式编程的核心机制,其本质远超 Java 接口——它支持状态(val/var)、具体实现、初始化逻辑及受控的多继承。关键原理在于编译器强制的线性化(Linearization)规则,确保 super 调用链唯一可预测;而混入(Mixin)机制则实现能力的结构化组合,避免抽象类单继承限制。这种设计赋予 Traits 独特的技术价值:既保障大型系统中横切关注点(如幂等、锁、可观测性)的高复用与低耦合,又要求开发者直面字段初始化顺序、this 引用泄漏、并发共享等真实工 阅读详情

这个例子来源于scala圣经级教程《Functional Programming in Scala》,由于本人跟着书中的代码敲了一遍,然后写了点测试代码验证了一下正确性,所以就放在这做个备忘吧。贴出来只是为了方便自己,如果看不懂,但是又感兴趣的就去看原书吧……

package state
import RNG.Simple
import state.State._

case class State[S, +A](run: S => (A, S)) {

  def map[B](f: A => B): State[S, B] = flatMap(a => unit(f(a)))


  def flatMap[B](f: A => State[S, B]): State[S, B] = State(s => {
    val (a, s1) = run(s)
    f(a).run(s1)
  })


  def map2[B, C](sb: State[S, B])(f: (A, B) => C): State[S, C] = flatMap(a => sb.map(b => f(a, b)))

}

object State {

  type Rand[A] = State[RNG, A]

  def unit[S, A](a: A): State[S, A] = State(s => (a, s))

  def get[S]: State[S, S] = State(s => (s, s))

  def set[S](s: S): State[S, Unit] = State(_ => ((), s))

  def modify[S](f: S => S): State[S, Unit] = for {
    s <- get
    _ <- set(f(s))
  } yield ()

  // The idiomatic solution is expressed via foldRight
  def sequenceViaFoldRight[S, A](sas: List[State[S, A]]): State[S, List[A]] =
    sas.foldRight(unit[S, List[A]](List()))((f, acc) =>  f.map2(acc)(_ :: _))


  def sequence[S, A](sas: List[State[S, A]]): State[S, List[A]] = {
    def go(s: S, actions: List[State[S,A]], acc: List[A]): (List[A], S) =
      actions match {
        case Nil => (acc.reverse, s)
        case h :: t => h.run(s) match { case (a,s2) => go(s2, t, a :: acc) }
      }
    State((s: S) => go(s, sas, List()))
  }

  def sequenceViaFoldLeft[S,A](l: List[State[S, A]]): State[S, List[A]] =
    l.reverse.foldLeft(unit[S, List[A]](List()))((acc, f) => f.map2(acc)( _ :: _ ))


  def main(args: Array[String]): Unit = {


    val simple = Simple(System.currentTimeMillis())
    println(simple)
    println(State.unit[RNG, Int](5).run(simple))


    val li5Ele = List.fill(5)(State.unit[RNG, Int](5))
    val sequenceFun = State.sequence(li5Ele)
    val sequenceVal = State.sequence(li5Ele).run(simple)
    println(sequenceVal)

    val li6Ele = List.fill(6)(State(RNG.int))

    val sequence6EleVal = State.sequence(li6Ele).run(simple)
    println(sequence6EleVal)


    val sequenceViaFoldRightVal = State.sequenceViaFoldRight(li6Ele).run(simple)
    println(sequenceViaFoldRightVal)


    val sequenceViaFoldLeftVal = State.sequenceViaFoldLeft(li6Ele).run(simple)
    println(sequenceViaFoldLeftVal)


    println(State.set(simple).run(simple)._1)
    println(State.set(simple).run(simple)._2)

    println("---------------------------------------------------------------")

    println(State.get.run(simple)._1)
    println(State.get.run(simple)._2)

    println("---------------------------------------------------------------")



    println(State.get[RNG].map[Int](_.nextInt._1).run(simple))
    println(State.get[RNG].map[RNG](_.nextInt._2).run(simple))


    //对传入的simple对象调用一次nextInt方法,从而转换为另一个simple对象
    println(State.set(simple.nextInt._2).run(simple))

    //对传入的simple对象调用一次nextInt方法,从而转换为另一个simple对象
    val modifyVal =State.modify((a: RNG) => a.nextInt._2).run(simple)
    println(modifyVal)


    ///////////////////////////////////////////////////////////////////////////////////////

    /**
      * 模拟交通灯颜色的变化
      * @param a
      * @return
      */
    def trafficLight(a: String): (String, String) = a match {
      case "红" => ("红", "绿")
      case "绿" => ("绿", "黄")
      case "黄" => ("黄", "红")
      case _    => ("红", "绿")
    }

    val li5 = List.fill(10)(State((a: String) => trafficLight(a)))
    val redStart = State.sequence[String, String](li5).run("红")
    println(redStart)

    val greenStart = State.sequence[String, String](li5).run("绿")
    println(greenStart)

    val xStart = State.sequence[String, String](li5).run("xxx")
    println(xStart)

    ///////////////////////////////////////////////////////////////////////////////////////


    val machine = Machine(true, 4, 0)
    val inputs = List(Coin, Turn, Coin, Turn, Coin, Turn, Coin, Turn, Coin, Turn, Coin, Turn)
    val machineRes = Candy.simulateMachine(inputs).run(machine)
    println(machineRes)

    val _machineRes = Candy._simulateMachine((inputs)).run(machine)
    println(_machineRes)

  }

}



sealed trait Input

/**
  * 表示一枚硬币
  */
case object Coin extends Input

/**
  * 表示糖果售货机的按钮
  */
case object Turn extends Input

/**
  * 表示糖果售货机:机器有2种输入方式,可以投入硬币,也可以按动按钮获取糖果
  *              机器有2种状态:锁定状态和非锁定状态
  */
case class Machine(locked: Boolean, candies: Int, coins: Int)

object Candy {

  /**
    * 对锁定的售货机投入硬币,如果有剩余的糖果它将变为非锁定状态
    * 对非锁定状态的售货机按下按钮,它将给出糖果并变回锁定状态
    * 对锁定状态的售货机按下按钮,或对非锁定状态的售货机投入硬币,什么也不做
    */
  def update = (i: Input) => (s: Machine) =>
    (i, s) match {
      case (_, Machine(_, 0, _)) => s

      case (Coin, Machine(false, _, _)) => s

      case (Turn, Machine(true, _, _)) => s

      case (Coin, Machine(true, candy, coin)) => Machine(false, candy, coin + 1)

      case (Turn, Machine(false, candy, coin)) => Machine(true, candy - 1, coin)
    }

  /**
    * 对一个糖果售货机建模的有限状态机
    */
  def simulateMachine(inputs: List[Input]): State[Machine, (Int, Int)] = for {
    _ <- sequence(inputs map (modify[Machine] _ compose update))
    s <- get
  } yield (s.coins, s.candies)


  /**
    * _simulateMachine is equal to simulateMachine, but not so brief
    * _simulateMachine contains debug statements
    */
  def _simulateMachine(inputs: List[Input]): State[Machine, (Int, Int)] = {

    val machines = for {
      ele <- inputs
    } yield  modify[Machine]({ print(ele); print("  "); update(ele)}) 
    // print(ele); print("  ") for debug purpose


    for {
      _ <- sequence(machines)
      s <- get
    } yield (s.coins, s.candies)

  }


}

上述代码的运行结果是:

Simple(1530871197922)
(5,Simple(1530871197922))
(List(5, 5, 5, 5, 5),Simple(1530871197922))
(List(760619510, 1890169447, -624214092, 759529940, -1356984262, -171369807),Simple(270244085079856))
(List(760619510, 1890169447, -624214092, 759529940, -1356984262, -171369807),Simple(270244085079856))
(List(760619510, 1890169447, -624214092, 759529940, -1356984262, -171369807),Simple(270244085079856))
()
Simple(1530871197922)
---------------------------------------------------------------
Simple(1530871197922)
Simple(1530871197922)
---------------------------------------------------------------
(760619510,Simple(1530871197922))
(Simple(49847960230981),Simple(1530871197922))
((),Simple(49847960230981))
((),Simple(49847960230981))
(List(红, 绿, 黄, 红, 绿, 黄, 红, 绿, 黄, 红),绿)
(List(绿, 黄, 红, 绿, 黄, 红, 绿, 黄, 红, 绿),黄)
(List(红, 绿, 黄, 红, 绿, 黄, 红, 绿, 黄, 红),绿)
((4,0),Machine(true,0,4))
Coin  Turn  Coin  Turn  Coin  Turn  Coin  Turn  Coin  Turn  Coin  Turn  ((4,0),Machine(true,0,4))

注:

代码中的RNG参见本人同类文章《用Scala实现一个纯函数风格的引用透明的伪随机数生成器》

从Lambda到集合抽象:真正提升函数式编程的抽象层次 函数式编程中,Lambda表达式常被视为简洁代码的象征,但它在提升抽象层次上存在天然边界。集合抽象(Set Abstraction)源于数学中的集合构造符,以声明式集合变换为核心,通过描述“集合应该变成什么”替代“如何遍历元素”,从而将代码表达从实现细节拉升至业务语义层。借助列表推导式、Stream API等工具,开发者能显著降低集合处理代码的认知负担,同时保持行为等价与可维护性。这一思想广泛应用于数据过滤、分组聚合、嵌套集合扁平化等典型场景,尤其适合中大型业务系统的渐进式重构。真正优雅的函数式代码,不是堆 阅读详情

相关推荐

Scala 在后端开发中的函数式编程应用

本文旨在全面解析Scala语言在后端开发中应用函数式编程范式的优势和实践方法。Scala如何融合面向对象和函数式编程范式函数式编程在后端开发中的核心优势Scala类型系统对构建健壮后端系统的支持使用Scala处理并发和异步编程的独特方法Scala生态系统中的主要框架和工具首先介绍Scala和函数式编程的基本概念然后深入探讨核心原理和算法实现接着通过实际项目案例展示应用方法最后分析生态系统和未来发展趋势Scala:一种多范式编程语言,结合了面向对象和函数式编程特性。

架构师的AI之路,分享AI应用开发架构的学习与实践。 824

Scala数据类型概述

Scala是完全面向对象的语言,这从其数据类型中就可以看出来。本文将对Scala中的数据类型进行简单的总结: (1)Scala中一切数据都是对象,都是Any的子类 (2)Scala中的数据类型默认分为两大类:数值类型(AnyVal)和引用类型(AnyRef),不管是什么类型的数据都是对象 (3)Scala中的数据类型仍然遵守低精度类型向高精度类型进行自动类型转换 (4)在书写上,基本数据类型开头的字母都是大写的,类似于Java中的包装类 关于Unit,Nothing和Null三者之间的区别将在另外一篇文章

weixin_43616627的博客 382

从单个API到多个API的Scala应用程序:性能与可扩展性

作者:禅与计算机程序设计艺术 1.1 Scala语言简介 Scala 是一门多用途语言,其主要特性包括:静态类型、支持函数式编程、简洁的语法、强大的抽象能力、面向对象编程、适用于JVM和服务器端开发等等。在很多开源项目中都可以看到Scala的身影,如 Apache Spark、Akka

AI天才研究院 3019

(八)Flink DataStream API 编程指南 - 4 状态与容错 (下)-- 数据类型与序列化

概览 数据类型 & 序列化 Apache Flink以一种独特的方式处理数据类型和序列化,它包含自己的类型描述符、泛型类型提取和类型序列化框架。本文档描述了这些概念及其背后的基本原理。 支持的数据类型 Flink对DataStream中的元素类型有一些限制。这样做的原因是系统分析类型来确定有效的执行策略。 以下是7类数据类型: Java Tuples and Scala Case Classes Java POJOs 基本数据类型 Regular Classes(普通类) Values Hadoo

京河小蚁的博客 700

一分钟理解 AP(Affinity Propagation) 亲和⼒传播算法

这篇博客发出来后,我用 Rust 复现代码出现问题。为此,我对对照了 sklearn 的相关代码,反复比较了两天,发现一处 bug,把 += 误写成了 =,导致数据量大的时候完全无法聚类。这个debug过程让我仔细梳理的 AP 算法的计算过程,今天我对这篇博客做了大规模修改,以便能原样展现原论文思想。

程序猿视角 3221

Nuvoton OpenTitan开源安全芯片技术解析与应用

硬件安全模块(HSM)作为可信计算基的核心组件,其设计透明度和可验证性正成为行业焦点。RISC-V架构凭借开源特性,为构建可审计的安全芯片提供了新范式。OpenTitan项目通过开放Verilog源码和形式化证明,实现了从物理不可克隆函数(PUF)到分层安全启动的全栈透明。该方案在lowRISC Voyager开发板上实测显示,安全启动时间小于200ms,性能损耗仅7%,显著优于传统黑盒方案。目前该技术已应用于Chromebook和数据中心,其40nm工艺版本更将功耗降至5μA待机水平,为物联网和边缘计算提

weixin_36303807的博客 404

flinkScala

package com. gu.networkflow_analysis import java.sql.Timestamp import java.text.SimpleDateFormat import org.apache.flink.api.common.functions.AggregateFunction import org.apache.flink.api.common.state.{ListState, ListStateDescriptor, MapState, MapStateD

weixin_43705952的博客 3018

Lumerical官方案例、FDTD时域有限差分法仿真学习(十三)——多模干涉耦合器(MMI)

计算通过 1×2 端口多模干涉 (MMI) 耦合器的宽带传输和光损耗。 使用设备 S 参数在 INTERCONNECT 中创建 MMI 的紧凑模型。 它还展示了如何使用 CML 编译器提取这些参数以生成紧凑模型。 一、概述 了解模拟工作流程和关键结果 低损耗光合路器和分路器是基于 Mach-Zehnder 的光调制器的基本组件,并且是集成电路的关键组成部分。通过在输入/输出波导处使用线性锥形确保输入/输出波导的模式与干涉区域之间的

weixin_45719141的博客 1万+

【Flink Scala】Flink状态管理

Flink状态管理Flink状态管理Flink中的状态有状态的算子和应用程序算子状态键控状态(keyed state)键控状态的代码实现状态编程实例 Flink状态管理 Flink中的状态 由一个任务维护,并且用来计算某个结果的所有数据,都属于这个任务的状态 可以认为状态就是一个本地变量,可以被任务的业务逻辑访问 Flink会进行状态管理,包括状态一致性、故障处理以及高效存储和访问,以便开发人员可以专注于应用程序的逻辑 再Flink中,状态始终与特定算子相关联 为了使运行时的Flink了解算子的状态,算.

HR的博客 953

中国裁判文书网案例批量爬取

本文介绍了某法院网站数据采集的技术研究过程,主要包含JS逆向分析和数据解密方法。通过开发者工具分析发现页面数据经过加密处理,重点研究了ciphertext等加密参数的生成逻辑。文章详细记录了定位加密函数、扣取加密代码、解密数据处理的全流程,并验证了解密方法的有效性。研究过程中强调了技术使用的法律边界,明确声明仅用于合法技术研究,禁止任何非法数据爬取行为。最终实现了加密数据的成功解密,并解释了各请求参数的作用,为后续数据清洗和存储奠定了基础。

2303_80825459的博客 817

基于STM32、HAL库的TLV320AIC3204IRHBR音频接口芯片驱动程序设计

* 开启所有数字部分 */#define TLV320AIC3204_REG_LEFT_HEADPHONE_OUT_VOLUME 0x0C /* 左声道耳机输出音量 */#define TLV320AIC3204_REG_DIGITAL_AUDIO_PATH_CONTROL 0x05 /* 数字音频路径控制 */#define TLV320AIC3204_REG_ANALOG_HP_FILTER_CONTROL 0x34 /* 模拟耳机滤波器控制 *//* 最大音量 */

corlin6688的博客 523

Spark Streaming状态管理函数(三)—MapWithState的使用(scala版)

Spark Streaming状态管理函数MapWithState的实现(scala版)

一个人的编程之路 5204

用 ABAP CDS Table Function 把复杂计算下沉到 SAP HANA:从定义到 AMDP 实战与 Clean Core 落地

摘要 CDS table function 是 SAP S/4HANA 开发中的关键工具,它允许在 ABAP CDS 中调用由 HANA 原生执行的函数逻辑,并以表形式返回结果集。其核心价值在于:弥补 CDS 表达式不足,将复杂计算(如排序、分组、币种换算等)安全地推送到数据库层执行,同时保持 CDS 的可组合性。实现方式是通过 AMDP 框架,在 ABAP 类中编写 SQLScript 代码。使用时需注意参数设计应区分业务语义与过滤条件,并严格遵守 client-safe 原则以避免跨客户端数据泄露风险。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 1007

19.DataStream API之State & Fault Tolerance(Working with State)

flink 1.9 State & Fault Tolerance 本文档解释了如何在开发应用程序时使用Flink的状态抽象。 Keyed State and Operator State Flink中有两种基本状态:key值状态Keyed State和操作算子状态Operator State。 Keyed State Keyed State总是与key相关,并且只...

木子李的博客 385

芒果YOLOv12改进13:独家原创改进最新 CFNet 核心结构|即插即用 | 首发改进显著提升检测性能,小目标检测涨点必备

芒果YOLOv12改进13:独家原创改进最新 CFNet 核心结构|即插即用 | 首发改进显著提升检测性能,小目标检测涨点必备

包括YOLOv5、YOLOv7、YOLOv8等模型改进 289

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

鸣潮后台挂机自动化:ok-ww 怎么自动战斗、清日常与刷声骸

每天上线先打寂灭、熔铸,再去乐园领奖励,一套日常做完近一小时。ok-ww 是一个基于图像识别的鸣潮自动化工具,通过模拟鼠标键盘输入完成自动战斗、一键日常与声骸刷取,游戏窗口最小化也能在后台跑。 [![鸣潮 ok-ww 后台自动战斗战斗场景](https://raw.gitcode.com/GitHub_Trending/ok/ok-wuthering-waves/raw/9ccccdef274f

gitblog_00266的博客 456

贝叶斯统计 [韦来生编]

贝叶斯(Bayes)统计是近几十年来迅速发展起来的数理统计的一个重要分支。贝叶斯方法与经典统计方法的主要不同之处是进行统计推断时除了利用样本信息外,还要利用参数的先验信息,因此可以提高统计推断或统计决策的效果。它在经济、金融、生物、医学、自然科学和社会科学等许多领域具有广泛的应用。贝叶斯方法的研究已渗透到了统计学的几乎所有领域。作者在给中国科学技术大学概率论与数理统计专业本科生开设的“数理统计”课程中有一章专门讲授“贝叶斯方法和统计决策理论”,近十年来也给中国科学技术大学概率统计专业研究生开设过几次“贝叶斯分析”课。本书是在对过去讲稿的内容作了适当的增减和调整的基础上完成的。  本书共分六章。第1章是绪论,介绍了贝叶斯统计的若干基本概念,同时对必要的数理统计的基础知识有重点地作了回顾。第二章介绍了确定先验分布的若干可供选择的方法。第三章介绍了几类常见统计模型参数的后验分布的主要结果和计算方法。第四章和第五章分别介绍了“贝叶斯统计推断”和“贝叶斯统计决策”的内容。第六章介绍了贝叶斯统计计算的若干方法,包括蒙特卡洛方法和马尔可夫链蒙特卡洛(MCMC)方法以及相关统计软件的简介。本书的每一章附右大量的例题和习题,书末附有常用的几个表格和部分习题解答供读者查用。  大约可在54学时内讲授本书的第1章至第六章的主要内容,教师可根据学时需要选讲本书第1章至第六章的部分内容。书中标“*”号的章节可略去不讲,留给读者作为阅读材料。第六章例题中的R代码和部分例题的数据文件等可从作者个人主页下载。  作者在编写本书的过程中参考了J.O.Berger教授的《统计决策论及贝叶斯分析》和茆诗松教授编写的《贝叶斯统计》等书中的一些内容,以及《贝叶斯分析》一书中由张伟平博士编写的有关贝叶斯统计计算的一些内容。在此表示衷心感谢。  本书编写准备过程中,中国科学技术大学统计与金融系的几个研究生帮助完成了本书部分中文的录入和排版,作者对他们的辛勤工作表示真诚的感谢。高等教育出版社为本书的出版给予了大力支持。在此一并致谢。

Flink Scala 示例项目指南

Flink Scala 示例项目指南 项目介绍 本项目源自 https://github.com/streaming-with-flink/examples-scala.git,是Apache Flink社区提供的一个专注于Scala语言编写的示例集合。这些示例旨在帮助开发者快速上手Flink,理解其核心概念,如数据流处理、状态管理、时间处理等,特别适合那些希望在Scala编程环境中利用Flin...

gitblog_00386的博客 589

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

从Scala循环里看函数式编程

我们用几分钟来想象一下自己是一名伐木工人,手里有林场里最好的斧子,因此你是工作效率最高的。突然有一天场里来了个推销的,他把一种新的砍树工具——链锯——给夸到了天上去。这人很有说服力,所以你也买了一把,不过你不懂得怎么用。你估摸着按照自己原来擅长的砍树方法,把链锯大力地挥向树干——不知道要先发动它。“链锯不过是时髦的样子货罢了”,没砍几下你就得出了这样的结论,于是把它丢到一边重新捡起用惯了的斧子。就...

cxlmap的博客 401

Scala语言的硬件驱动

Scala是一种运行在Java虚拟机上的多范式编程语言,结合了面向对象和函数式编程的特点。自2003年首次发布以来,Scala逐渐受到了开发者的青睐,尤其在大数据处理和分布式计算领域,称得上是Apache Spark的重要开发语言。

2501_91534395的博客 1752

Requests-Scala:Scala开发者的终极HTTP客户端解决方案

Requests-Scala是Python知名HTTP客户端库Requests的Scala移植版本,为Scala开发者提供了一种灵活、直观且易于使用的HTTP客户端解决方案。如果你正在寻找一个简单高效的Scala HTTP客户端库,Requests-Scala绝对是你的最佳选择!🚀 ## 为什么选择Requests-Scala? 在Scala生态系统中,HTTP客户端库众多,如Akka-ht

gitblog_00124的博客 300

Kafka Streams Scala 迁移指南:从 kafka-streams-scala 迁移到 Java API(含 WordCount 实战与源码解析)

> **导读**:本文基于 Apache Kafka 官方迁移文档编写,面向正在使用或计划使用 `kafka-streams-scala` 库的 Scala 开发者。该库自 Kafka 4.3 起正式标记为废弃(deprecated),并将在 Kafka 5.0 中移除。读完本文,你将掌握从 Scala 包装 API 平滑迁移到 Java Streams API 的核心差异、Serde 配置的两种

gitblog_00989的博客 494

Scala 专家 Agent 深度解析:面向企业级函数式编程与分布式系统的 Scala 技术画像

> 本篇文章围绕 agents24 开源仓库中 [scala-pro Agent 定义](https://link.gitcode.com/i/8ad1fba558049c97de72ddc87cff7506) 展开,系统性拆解这份面向企业级 Scala 工程的技术能力画像。文章将结合仓库中的 [Agent 目录](https://link.gitcode.com/i/390376330c771a

gitblog_01129的博客 898

Scala中方法与函数的本质区别:从JVM字节码到工程实践

在Scala中,'方法'(method)是类的成员行为,编译为JVM原生实例方法,不可序列化、不可赋值;而'函数'(function)是运行时的一等值对象,实现自FunctionN特质,具备可组合、可序列化、可高阶传递等特性。这一差异源于Scala融合面向对象与函数式编程的核心设计哲学,直接影响高阶函数调用、闭包捕获、序列化、热更新等关键工程场景。理解def与val定义的调用体在字节码层面的生成机制(如eta-expansion是否发生、是否生成FunctionN子类),是写出健壮、可维护、高性能Scala

weixin_34133829的博客 1113

Scala 中的函数式编程基础

主要来自 Scala 语言发明人 Martin Odersky 教授的 Coursera 课程 《Functional Programming Principles in Scala》。 ------------------------------部分一--------------------------------------- 很久以前写过一个非常简单的

GarfieldEr007的专栏 1749

为什么选择Indigo?探索Scala函数式游戏开发的终极优势

Indigo是一个基于Scala的函数式游戏引擎,它将函数式编程的优雅与游戏开发的创造力完美结合,为开发者提供了构建可靠、可维护游戏的全新方式。无论是独立游戏开发者还是专业团队,都能通过Indigo体验到函数式编程带来的独特优势。 ## 🚀 函数式编程:游戏开发的未来趋势 函数式编程(FP)以其不可变性、纯函数和声明式风格,正在改变软件开发的格局。在游戏开发领域,这些特性尤为重要: - *

gitblog_00901的博客 439
上一篇: 用Scala实现一个纯函数风格的引用透明的伪随机数生成器
下一篇: 使用Scala实现一个并发库(阻塞版本, 下一篇文章提供NonBlocking版本)
lhever_
博客等级 码龄14年 213粉丝 130原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值