函数式编程的技巧

14.1.2 科里化

给出科里化的理论定义之前,让我们先来看一个例子。应用程序通常都会有国际化的需求将一套单位转换到另一套单位是经常碰到的问题。

单位转换通常都会涉及转换因子以及基线调整因子的问题。比如,将摄氏度转换到华氏度的公式是CtoF(x)=x*9/5 +32。

所有的单位转换几乎都遵守下面这种模式:(1)乘以转换因子

(2)如果需要,进行基线调整

你可以使用下面这段通用代码表达这一模式:

static double converter(double x,double f,double b){return x*f+bi

这里x是你希望转换的数量,是转换因子,b是基线值。但是这个方法有些过于宽泛了。通常,你还需要在同一类单位之间进行转换,比如公里和英里。当然,你也可以在每次调用converter方法时都使用3个参数,但是每次都提供转换因子和基准比较繁琐,并且你还极有可

能输人错误。当然,你也可以为每一个应用编写一个新方法,不过这样就无法对底层的逻辑进行复用。这里我们提供一种简单的解法,它既能充分利用已有的逻辑,又能让converter针对每个应用进行定制。你可以定义一个“工厂”方法,它生产带一个参数的转换方法,我们希望借此来说明科里化。下面是这段代码:

static DoubleUnaryOperator curriedConverter(double f, double b){return (double x)->x*f + b;

现在,你要做的只是向它传递转换因子和基准值(和b),它会不辞辛劳地按照你的要求返回一个方法(使用参数x)。比如,你现在可以按照你的需求使用工厂方法产生你需要的任何Converter:

现在,你要做的只是向它传递转换因子和基准值(和b),它会不辞辛劳地按照你的要求返回一个方法(使用参数x)。比如,你现在可以按照你的需求使用工厂方法产生你需要的任何
converter:
 

DoubleUnaryOperator convertCtoF= curriedConverter(9.0/5,32);DoubleUnaryOperator convertUSDtoGBP = curriedConverter(0.6,0);DoubleUnaryOperatorconvertKmtoMi=curriedConverter(0.6214.0);
由于DoubleUnaryoperator定义了方法applyAsDouble,你可以像下面这样使用你的
converter:
double gbp =convertUsDtoGBP.applyAsDouble(1000);


这样一来,你的代码就更加灵活了,同时它又复用了现有的转换逻辑!让我们一起回顾下你都做了哪些工作。你并没有一次性地向converter方法传递所有的参数x、和b,相反,你只是使用了参数和b并返回了另一个方法,这个方法会接收参数x,最终返回你期望的值x*f+b。通过这种方式,你复用了现有的转换逻辑,同时又为不同的转换因子创建了不同的转换方法。

14.2.1 破坏式更新和函数式更新的比较


让我们看看不这么做会导致怎样的结果。假设你需要使用一个可变类rainJourney(利用一个简单的单向链接列表实现)表示从A地到B地的火车旅行,你使用了一个整型字段对旅程的一些细节进行建模,比如当前路途段的价格。旅途中你需要换乘火车,所以需要使用几个由onwara字段串联在一起的TrainJourney对象;直达火车或者旅途最后一段对象的onward字段为nu11:

class TrainJourneypublic int price;public TrainJourney onward;public TrainJourney(int p,TrainJourneyt){price =Pionward =ti


假设你有几个相互分隔的+rainJourney对象分别代表从X到Y和从Y到Z的旅行。你希望创建一段新的旅行,它能将两个TrainJourney对象串接起来(即从X到Y再到Z)。一种方式是采用简单的传统命令式的方法将这些火车旅行对象链接起来,代码如下:

static TrainJourney link(TrainJourney a,Traindourney b){if (a==null)return biTrainJourney taiwhile(t.onward != nu1l){t = t.onward:
t.onward =bi
return a


这个方法是这样工作的,它找到™rainJourney对象a的下一站,将其由表示a列表结束的nu11替换为列表b(如果a不包含任何元素,你需要进行特殊处理)。这就出现了一个问题:假设变量firstJourney包含了从X地到Y地的线路,另一个变量secondJourney包含了从Y地到Z地的线路,如果你调用1ink(firstJourney,secondJourney方法,这段代码会破坏性地更新firstJourney,结果secondJourney也会加被入到firstJourney,最终请求从X地到Z地的用户会如其所愿地看到整合之后的旅程,不过从X地到Y的京科H被建区州曲再就元上期
 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/389628.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【高级C语言】从汇编代码看volatile关键字的作用

本人就职于国际知名终端厂商,负责modem芯片研发。 在5G早期负责终端数据业务层、核心网相关的开发工作,目前牵头6G算力网络技术标准研究。 博客内容主要围绕: 5G/6G协议讲解 算力网络讲解(云计算,边缘计…

apk反编译修改教程系列---简单去除apk登陆 修改vip与一些反编译基础常识【十二】

往期教程: 安卓玩机-----反编译apk 修改apk 去广告 去弹窗等操作中的一些常识apk反编译修改教程系列-----修改apk应用名称 任意修改名称 签名【一】 apk反编译修改教程系列-----任意修改apk版本号 版本名 防止自动更新【二】 apk反编译修改教程系列-----修改apk中…

政安晨:【示例演绎】【Python】【Numpy数据处理】快速入门(二)

环境准备 大家如果第一次看到,可以先从我这个演绎系列的第一篇文章开始,包括准备环境等等。 第一篇文章如下: 政安晨:【示例演绎】【Python】【Numpy数据处理】快速入门(一)https://blog.csdn.net/snowd…

怎么搭建自己的网站?

怎么搭建自己的网站 一.领取一个免费域名和SSL证书,和CDN 特点:支持Cloudflare CDN Cloudflare是全球知名的CDN提供商,如果你不想暴露你的源站,又想使用我们的二级域名,不需要前往Cloudflare添加域名,修…

【Linux取经路】文件系统之被打开的文件——文件描述符的引入

文章目录 一、明确基本共识二、C语言文件接口回顾2.1 文件的打开操作2.2 文件的读取写入操作2.3 三个标准输入输出流 三、文件有关的系统调用3.1 open3.1.1 比特位级别的标志位传递方式 3.2 write3.2.1 模拟实现 w 选项3.2.2 模拟实现 a 选项 3.3 read 四、访问文件的本质4.1 再…

STM32,嵌入式系统中的I2C协议

I2C协议——读写EEPROM 关注我,共同交流,一起成长 前言一、协议简介二、I2C特性及架构三、通信过程 前言 这是一种主要用于集成电路和集成电路(IC)通信,计算机中复杂的问题大多数就是用分层来进行解决,这个…

k8s-项目部署案例

一、容器交付流程 在k8s平台部署项目流程 在K8s部署Java网站项目 DockerFile 如果是http访问,需要在镜像仓库配置可信任IP 三、使用工作负载控制器部署镜像 建议至少配置两个标签 一个是声明项目类型的 一个是项目名称的 继续配置属性 资源配额 健康检查 五、使…

积分(二)——复化Simpson(C++)

前言 前言 simpson积分 simpson积分公式 ∫ a b f ( x ) d x ≈ b − a 6 [ f ( a ) f ( b ) 4 f ( a b 2 ) ] \int_{a}^{b}f(x)dx \approx \frac{b-a}{6}[f(a)f(b)4f(\frac{ab}{2})] ∫ab​f(x)dx≈6b−a​[f(a)f(b)4f(2ab​)] 与梯形积分类似,当区间[a,b]较…

Java 和 JavaScript 的奇妙协同:语法结构的对比与探索(下)

🤍 前端开发工程师、技术日更博主、已过CET6 🍨 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 🕠 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 🍚 蓝桥云课签约作者、上架课程《Vue.js 和 E…

卷积神经网络的基本结构

卷积神经网络的基本结构 与传统的全连接神经网络一样,卷积神经网络依然是一个层级网络,只不过层的功能和形式发生了变化。 典型的CNN结构包括: 数据输入层(Input Layer)卷积层(Convolutional Layer&#x…

社区商铺开什么店最好?从商业计划书到实际运营

在社区商铺开店,选择适合的业态是成功的关键。作为一名开店 5 年的资深创业者,我想分享一些关于社区店的干货和见解。 这篇文章,我用我的项目给大家举例子! 鲜奶吧作为一种新兴的业态,以提供新鲜、健康的乳制品为主&…

vue3 之 倒计时函数封装

理解需求 编写一个函数useCountDown可以把秒数格式化为倒计时的显示xx分钟xx秒 1️⃣formatTime为显示的倒计时时间 2️⃣start是倒计时启动函数,调用时可以设置初始值并且开始倒计时 实现思路分析 安装插件 dayjs npm i dayjs倒计时逻辑函数封装 // 封装倒计时…

C++类和对象-多态->多态的基本语法、多态的原理剖析、纯虚函数和抽象类、虚析构和纯虚析构

#include<iostream> using namespace std; //多态 //动物类 class Animal { public: //Speak函数就是虚函数 //函数前面加上virtual关键字&#xff0c;变成虚函数&#xff0c;那么编译器在编译的时候就不能确定函数调用了。 virtual void speak() { …

流量主小程序/公众号h5开源代码 源码分享

小程序开源代码合集 1、网课搜题小程序源码/小猿题库多接口微信小程序源码自带流量主 搭建教程 1、微信公众平台注册自己的小程序 2、下载微信开发者工具和小程序的源码 3、上传代码到自己的小程序 界面截图&#xff1a; 开源项目地址&#xff1a;https://ms3.ishenglu.com…

python 人脸检测器

import cv2# 加载人脸检测器 关键文件 haarcascade_frontalface_default.xml face_cascade cv2.CascadeClassifier(haarcascade_frontalface_default.xml)# 读取图像 分析图片 ren4.png image cv2.imread(ren4.png) gray cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)# 进行人脸…

php基础学习之函数

基本概念 是一种语法结构&#xff0c;将实现某一个功能的代码块封装到一个结构中&#xff0c;从而实现代码的重复利用 php函数的定义语法 &#xff08;与C/Java很类似&#xff0c;区别在于没有数据类型&#xff0c;因为php是弱类型语言&#xff09; function 函数名(参数){ //…

波奇学Linux:文件系统打开文件

从文件系统来看打开文件 计算机系统和磁盘交互的大小是4kb 物理内存的4kb&#xff0c;磁盘的4kb文件叫做页帧 磁盘数据块的以4kb为单位。 减少IO的次数&#xff0c;减少访问外设的次数--硬件 基于局部性的原理&#xff0c;预加载机制--软件 操作系统管理内存 操作系统对…

leetcode hot 100最小花费爬楼梯

本题和之前的爬楼梯类似&#xff0c;但是需要考虑到花费的问题&#xff01;**注意&#xff0c;只有在爬的时候&#xff0c;才花费体力&#xff01;**那么&#xff0c;我们还是按照动态规划的五部曲来思考。 首先我们要确定dp数组的含义&#xff0c;那么就是我们爬到第i层所花费…

[嵌入式AI从0开始到入土]14_orangepi_aipro小修补含yolov7多线程案例

[嵌入式AI从0开始到入土]嵌入式AI系列教程 注&#xff1a;等我摸完鱼再把链接补上 可以关注我的B站号工具人呵呵的个人空间&#xff0c;后期会考虑出视频教程&#xff0c;务必催更&#xff0c;以防我变身鸽王。 第1期 昇腾Altas 200 DK上手 第2期 下载昇腾案例并运行 第3期 官…

DDR简单了解

DDR全称为 double data rate Synchronous Dynamic Random Access Memory 既DDR SDRAM。 顾名思义需要依次了解这些名词DRAM, SDRAM, DDR, DDR2, DDR3, DDR4。因为这些名词代表DRAM发展的不同阶段&#xff0c;它们是内存的同一条技术路线&#xff0c;核心都是使用一个晶体管和一…