【PL理论】(22) 函数式语言:多参数 | 柯里化 (Currying) : 将多参数函数实现为返回一个函数的函数

  • 💭 写在前面:本章我们将继续讲解函数式语言,介绍多参数,着重讲解柯里化的概念,将多参数函数实现为返回一个函数的函数。

目录

0x00 多参数(Multiple Arguments)

0x01 柯里化(Currying)


0x00 多参数(Multiple Arguments)

我们可以定义一个带有多个参数的函数吗?比如一个将两个整数参数相加的函数。

事实上,这在我们的 F- 语言中已经是可能的了。

在下面的代码中,函数 f 被定义为接受参数 x 并返回一个函数:(fun y -> x + y)

然后 f 3 2 被解释为 (f 3) 应用到 2

事实上,如果你在 F# 代码中写 let f x y = x + y,它在内部也是这样处理的:

// let f x y = x + y  可以这么写
let f = fun x -> (fun y -> x + y) in
f 3 2    // 把它想成 (f 3) 2

刚才那个概念,我们称之为 柯里化 (currying) ,将多参数函数实现为返回一个函数的函数。

柯里化使得函数的部分应用成为可能,例如我们可以定义如下的函数 inc,

它接受一个整数并返回增加 1 的整数,这在原版的 F# 语言和我们的 F- 语言中都是可能的。

let f = fun x -> (fun y -> x + y) in
let inc = f 1 in
let a = inc 7      // a 将被定义为 8
...

0x01 柯里化(Currying)

"优雅而灵巧的函数转换技术"

柯里化 (currying) 是一种函数式编程技术,它将一个接受多个参数的函数转换为一系列只接受一个参数的函数。这种技术以逻辑学家 Haskell Curry 的名字命名,尽管他并不是第一个提出这个概念的人。

在传统的多参数函数中,函数一次性接收所有参数并返回结果。例如,有一个函数 f(x, y, z)

def f(x, y, z):
    return x + y + z

通过 currying,可以将这个函数转换为一系列接受单一参数的函数:

def curried_f(x):
    def g(y):
        def h(z):
            return x + y + z
        return h
    return g

# 调用方法
result = curried_f(1)(2)(3)  # result 为 6

优点:

① 部分应用 Currying 可以方便地固定某些参数,从而生成一个新函数。例如:

add_to_five = curried_f(5)
result = add_to_five(2)(3)  # result 为 10

② 函数组合: Currying 支持更灵活的函数组合和重用,使得编写高阶函数变得更加简单。

③ 代码简洁性: 在某些情况下,currying 可以使代码更简洁、更具可读性。

许多函数式编程语言原生支持 currying。

在 JavaScript 中我们也可以手动实现,或者使用 Lodash 库的内置函数:

function curriedAdd(x) {
    return function(y) {
        return function(z) {
            return x + y + z;
        };
    };
}

const addToFive = curriedAdd(5);
const result = addToFive(3)(2);  // result 为 10


📌 [ 笔者 ]   王亦优
📃 [ 更新 ]   2024.6.10
❌ [ 勘误 ]   /* 暂无 */
📜 [ 声明 ]   由于作者水平有限,本文有错误和不准确之处在所难免,
              本人也很想知道这些错误,恳望读者批评指正!

📜 参考资料 

Microsoft. MSDN(Microsoft Developer Network)[EB/OL]. []. .

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

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

相关文章

Android framework的Zygote源码分析

文章目录 Android framework的Zygote源码分析linux的fork Android framework的Zygote源码分析 init.rc 在Android系统中,zygote是一个native进程,是Android系统上所有应用进程的父进程,我们系统上app的进程都是由这个zygote分裂出来的。zyg…

AI虚拟试穿技术:开启高保真、多场景、多样化服装组合的试穿应用

随着电子商务的快速发展,消费者对于在线购物体验的要求越来越高。特别是在服装领域,消费者渴望能够在购买前直观地了解服装的试穿效果。传统的虚拟试穿技术虽然已有一定的发展,但在不同场景下的高保真度和鲁棒性方面仍面临挑战。为此,我们研发了一种全新的AI虚拟试穿技术,…

电脑开机之后要很久才能进入系统?进入WinPE也是卡顿半天?

前言 小白最近接到了一张很奇怪的电脑维修单,客户说他的工作室电脑开机特别慢,开机之后特别卡顿,在使用的时候也会一卡一卡的。 这事情开始看很简单:估计就是电脑还是机械硬盘,所以开机很慢又卡顿。所以应该是把机械…

vi/vim使用命令

你是否在编辑文件时以为键盘坏了,为什么不能删除呢,为什么不能敲代码呢,等你初识vi,会觉得这个东西为什么设计得这么难用,这篇教程带你熟练得用上这款经典的工具 Vi 是在 Unix 系统上广泛使用的编辑器,Vim …

【车载音视频电脑】嵌入式AI分析车载DVR,支持8路1080P

产品特点 采用H.265 & H.264编解码,节约存储空间、传输流量; 高分辨率:支持8路1080P*15FPS/4路1080P*30FPS、720P、D1等编解码; 支持1张SATA硬盘,取用方便,满足大容量存储要求; 支持1个…

安装台式电脑网卡驱动

安装电脑网卡驱动 1. 概述2. 具体方法2.1 先确定主板型号2.2 详细操作步骤如下2.2.1 方法一2.2.2 方法二2.2 主流主板官网地址 结束语 1. 概述 遇到重装系统后、或者遇到网卡驱动出现问题没有网络时,当不知道怎么办时,以下的方法,可以作为一…

oracle RAC安装 保姆级教程

使用SSHXmanager 我的本地IP是172.17.68.68 服务器配置 [rootrac12-1 ~]# cat /etc/hosts 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 #Public IP …

笔记 | 用go写个docker

仅作为自己学习过程的记录,不具备参考价值 前言 看到一段非常有意思的话: 很多人刚接触docker的时候就会感觉非常神奇,感觉这个技术非常新颖,其实并不然,docker使用到的技术都是之前已经存在过的,只不过旧…

网络安全等级保护基本要求解读- 安全计算环境-应用系统和数据安全

概述 越来越多的企业用户已将核心业务系统转移到网络上,Web浏览器成为业 务系统的窗口,应用系统面临更多的安全威胁;并且由于各种原因使得其 存在较多的安全漏洞。 在此背景下,如何保障企业的应用安全,尤其是Web应用…

使用PyMuPDF、Pillow和pytesseract实现PDF文件中文OCR识别

文章目录 一、Win11下安装Tesseract和中文语言包(tessdata)1.1 安装Tesseract OCR引擎1.1.1 下载Tesseract OCR安装包1.1.2 运行安装程序1.2 安装中文语言包(tessdata)1.2.1 下载中文语言包1.2.2 放置中文语言包1.3 配置环境变量1.3.1 打开系统属性1.3.2 编辑环境变量1.4 测…

计算机视觉全系列实战教程:(九)图像滤波操作

1.图像滤波的概述 (1)Why (为什么要进行图像滤波) 去噪:去除图像在获取、传输等过程中的各种噪音干扰提取特征:使用特定的图像滤波器提取图像特定特征 (2)What (什么是图像滤波) 使用滤波核对图像进行卷积运算或非线性运算,以达到去噪或提…

腾讯云EdgeOne对比普通CDN的分别

EdgeOne架构图 普通CDN架构图 ​​​​​​​ 腾讯云EdgeOne对比普通CDN的不同点 服务范围和集成度 腾讯云EdgeOne是一体化的综合平台,不仅提供内容分发功能,还包括安全防护、性能优化和边缘计算等服务。EdgeOne提供了DDoS防护、WAF(Web应…

vue3+vite:动态引入静态图片资源

目录 第一章 前言 第二章 vue2与vue3动态引入静态图片资源 2.1 vue2 webpack动态引入静态图片资源 2.1.1 了解 2.1.2 vue2项目动态引入静态图片资源 2.2 vue3 vite动态引入静态图片资源 2.2.1 了解 2.2.2 require vs import了解 2.2.3 vue3vite 项目动态引入静态图片…

路由器怎么设置局域网?

局域网(Local Area Network,LAN)是指在一个相对较小的地理范围内,如家庭、办公室或学校等,通过路由器等设备连接起来的计算机网络。设置局域网可以方便地实现内部资源共享和信息交流。本文将介绍如何设置局域网以及一个…

12.实战私有数据微调ChatGLM3

实战私有数据微调ChatGLM3 实战私有数据微调ChatGLM3实战构造私有的微调数据集基于 ChatGPT 设计生成训练数据的 Prompt使用 LangChain GPT-3.5-Turbo 生成训练数据样例训练数据解析、数据增强和持久化存储自动化批量生成训练数据集流水线提示工程(Prompt Engineer…

爬虫-模拟登陆博客

import requests from bs4 import BeautifulSoupheaders {user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36 } # 登录参数 login_data {log: codetime,pwd: shanbay520,wp-submit: …

Undertow学习

Undertow介绍 Undertow是一个用java编写的灵活、高性能的web服务器,提供基于NIO的阻塞和非阻塞API。 Undertow有一个基于组合的体系结构,允许您通过组合小型单用途处理程序来构建web服务器。为您提供了在完整的Java EE servlet 4.0容器或低级别非阻塞处…

N32G45XVL-STB之移植LVGL(8.4.0)

目录 概述 1 系统软硬件 1.1 软件版本信息 1.2 ST7796-LCD 1.3 MCU IO与LCD PIN对应关系 2 认识LVGL 2.1 LVGL官网 2.2 下载V8.4.0 3 移植LVGL 3.1 硬件驱动实现 3.2 添加LVGL库文件 3.3 移植和硬件相关的代码 3.3.1 驱动接口相关文件介绍 3.3.2 重新接口函数 3…

SwiftUI中UIViewRepresentable的使用(UIKit与SwiftUI的桥梁)

UIViewRepresentable是一个协议,用于创建一个SwiftUI视图,该视图包装了一个UIKit视图。通过实现UIViewRepresentable协议,我们可以在SwiftUI中使用自定义的UIKit视图,并与SwiftUI进行交互。 实现UIViewRepresentable 创建一个遵…

Flink任务如何跑起来之 2.算子 StreamOperator

Flink任务如何跑起来之 2.算子 StreamOperator 前文介绍了Transformation创建过程,大多数情况下通过UDF完成DataStream转换中,生成的Transformation实例中,核心逻辑是封装了SimpleOperatorFactory实例。 UDF场景下,DataStream到…