首页  >  文章  >  web前端  >  TypeScript 中的函数式编程

TypeScript 中的函数式编程

Patricia Arquette
Patricia Arquette原创
2024-10-19 22:32:29578浏览

Functional Programming in TypeScript

内容

  1. 简介
  2. TypeScript 环境
  3. 通过函数表示数据
    1. 套装
    2. 二元运算
    3. 走得更远
  4. 欧几里得平面
    1. 绘制圆盘
    2. 绘制水平和垂直半平面
    3. 功能
    4. 走得更远
  5. 分形
    1. 复数和绘图
    2. 曼德尔布罗分形
    3. 走得更远

您可以在这里找到源代码:https://github.com/aelassas/function-ts

介绍

在 TypeScript 中,函数只不过是对象。因此,可以构造函数、作为参数传递、从函数返回或分配给变量。因此,TypeScript 具有一流的功能。更准确地说,TypeScript 支持以下内容:

  • 高阶函数参数
  • 高阶函数结果
  • 嵌套函数
  • 匿名函数
  • 关闭
  • 部分应用(ECMAScript 5)

本文不会讨论函数式编程的基础知识,因为您可以在互联网上找到有关此主题的大量资源。相反,它将讨论 TypeScript 中应用于代数、数字、欧几里得平面和分形的函数式编程。本文提供的示例将从简单到复杂,但始终以简单、直接且易于理解的方式进行说明。

TypeScript 环境

要运行源代码,您需要安装 Node.js。安装 Node.js 后,下载源代码存档,解压它,转到在终端上解压的源代码文件夹,设置 TypeScript 环境并使用以下命令安装所有必需的依赖项:

npm install

要运行数字的演示,请运行以下命令:

npm run numbers

要运行欧几里得平面的演示,请运行以下命令:

npm run plane

要运行分形演示,请运行以下命令:

npm run fractals

通过函数表示数据

设 S 为任意元素 a、b、c ... 的集合(例如,桌子上的书或欧几里得平面上的点),并设 S' 为这些元素的任意子集(例如,桌子上的绿色书籍或以欧几里德平面原点为圆心的半径为 1 的圆中的点)。

集合 S' 的特征函数 S'(x) 是将 S 的每个元素 x 与 true 或 false 相关联的函数。

S'(x) = true if x is in S'
S'(x) = false if x is not in S'

令 S 为桌子上的一套书,让 S' 为桌子上的一套绿书。设a和b是桌上的两本绿书,c和d是桌上的两本红书。然后:

npm install

设 S 为欧几里德平面中点的集合,令 S' 为以欧几里德平面原点 (0, 0)(单位圆)为中心、半径为 1 的圆中点的集合。设a和b为单位圆中的两点,c和d为以欧几里德平面原点为圆心、半径为2的圆中的两点。然后:

npm run numbers

因此,任何集合S'总是可以用它的特征函数来表示。该函数接受一个元素作为参数,如果该元素位于 S' 中,则返回 true,否则返回 false。换句话说,集合(抽象数据类型)可以通过 TypeScript 中的函数来表示。

npm run plane

在接下来的部分中,我们将了解如何通过 TypeScript 以函数式方式表示集合代数中的一些基本集合,然后我们将定义集合上的通用二元运算。然后,我们将这些运算应用于数字,然后应用于欧几里得平面的子集。集合是抽象数据结构,数字的子集和欧几里得平面的子集是抽象数据结构的表示,最后的二元运算是适用于抽象数据结构的任何表示的通用逻辑。

本节介绍集合代数中一些基本集合通过 TypeScript 的表示。

空集

Functional Programming in TypeScript

设E为空集,并清空其特征函数。在集合代数中,E 是没有元素的唯一集合。因此,Empty 可以定义如下:

npm run fractals

因此,E 在 TypeScript 中的表示可以定义如下:

S'(x) = true if x is in S'
S'(x) = false if x is not in S'

在集合代数中,Empty 表示如下:

Functional Programming in TypeScript

因此,运行以下代码:

S'(a) = S'(b) = true
S'(c) = S'(d) = false

给出以下结果:

Functional Programming in TypeScript

全部设置

Functional Programming in TypeScript

设 S 为集合,S' 为包含所有元素及其所有 特征函数 的 S 子集。在集合代数中,S' 是包含所有元素的完整集合。因此,All 可以这样定义:

S'(a) = S'(b) = true
S'(c) = S'(d) = false

因此,S' 在 TypeScript 中的表示可以定义如下:

type Set<T> = (x: T) => boolean

在集合代数中,All 表示如下:

Functional Programming in TypeScript

因此,运行以下代码:

npm install

给出以下结果:

Functional Programming in TypeScript

单例集

设 E 为 Singleton 集合,Singleton 为其特征函数。在集合代数中,E 也称为单位集或一元组,是只有一个元素 e 的集合。因此,Singleton可以定义如下:

npm run numbers

因此,E 在 TypeScript 中的表示可以定义如下:

npm run plane

因此,运行以下代码:

npm run fractals

给出以下结果:

Functional Programming in TypeScript

其他套装

本节介绍整数集的子集。

偶数

设E是偶数集合,Even是它的特征函数。在数学中,偶数是二的倍数。因此,Even 可以定义如下:

S'(x) = true if x is in S'
S'(x) = false if x is not in S'

因此,E 在 TypeScript 中的表示可以定义如下:

S'(a) = S'(b) = true
S'(c) = S'(d) = false

因此,运行以下代码:

S'(a) = S'(b) = true
S'(c) = S'(d) = false

给出以下结果:

Functional Programming in TypeScript

奇数

设E为奇数集合,Odd为其特征函数。在数学中,奇数是指不是二的倍数的数。因此,Odd 可以定义如下:

type Set<T> = (x: T) => boolean

因此,E 在 TypeScript 中的表示可以定义如下:

Empty(x) = false if x is in E
Empty(x) = false if x is not in E

因此,运行以下代码:

const empty = () => (e: T) => false

给出以下结果:

Functional Programming in TypeScript

3的倍数

设 E 为 3 的倍数集,MultipleOfThree 是其特征函数。在数学中,3的倍数是能被3整除的数。因此,MultipleOfThree可以定义如下:

console.log('\nEmpty set:')
console.log('Is 7 in {}?', common.empty()(7))

因此,E 在 TypeScript 中的表示可以定义如下:

All(x) = true if x is in S

因此,运行以下代码:

const all = () => (e: T) => true

给出以下结果:

Functional Programming in TypeScript

5的倍数

设 E 为 5 的倍数集,MultipleOfFive 为其特征函数。在数学中,5的倍数是能被5整除的数。因此,MultipleOfFive可以定义如下:

npm install

因此,E 在 TypeScript 中的表示可以定义如下:

npm run numbers

因此,运行以下代码:

npm run plane

给出以下结果:

Functional Programming in TypeScript

素数

很久以前,当我在玩 Project Euler 问题时,我必须解决以下问题:

npm run fractals

为了解决这个问题,我首先必须编写一个快速算法来检查给定的数字是否是素数。算法编写完成后,我编写了一个迭代算法,迭代素数,直到找到第 10 001 个素数。

设 E 为素数集,并素其特征函数。在数学中,素数是大于 1 的自然数,除了 1 和它本身之外没有正因数。因此,Prime可以定义如下:

S'(x) = true if x is in S'
S'(x) = false if x is not in S'

因此,E 在 TypeScript 中的表示可以定义如下:

S'(a) = S'(b) = true
S'(c) = S'(d) = false

因此,运行下面的代码来解决我们的问题:

S'(a) = S'(b) = true
S'(c) = S'(d) = false

其中 getPrime 定义如下:

type Set<T> = (x: T) => boolean

给出以下结果:

Functional Programming in TypeScript

二元运算

本节介绍了从给定集合构造新集合和操作集合的几个基本操作。下面是集合代数中的文氏图。

Functional Programming in TypeScript

联盟

Functional Programming in TypeScript

设E和F是两个集合。 E 和 F 的,用 E U F 表示,是属于 E 和 F 的成员的所有元素的集合。

让 Union 成为 并集 操作。因此,Union 操作可以在 TypeScript 中实现如下:

Empty(x) = false if x is in E
Empty(x) = false if x is not in E

运行以下代码:

const empty = () => (e: T) => false

给出以下结果:

Functional Programming in TypeScript

路口

Functional Programming in TypeScript

设E和F是两个集合。 E 和 F 的交集,用 E n F 表示,是同时属于 E 和 F 成员的所有元素的集合。

设 Intersection 为 交集 运算。因此,Intersection 操作可以在 TypeScript 中实现如下:

console.log('\nEmpty set:')
console.log('Is 7 in {}?', common.empty()(7))

运行以下代码:

All(x) = true if x is in S

给出以下结果:

Functional Programming in TypeScript

笛卡尔积

Functional Programming in TypeScript

设E和F是两个集合。 E 和 F 的笛卡尔积,用 E × F 表示,是所有有序对 (e, f) 的集合,使得 e 是 E 的成员,f 是 F 的成员。

令 CartesianProduct 为 笛卡尔积 运算。因此,CartesianProduct 运算可以在 TypeScript 中实现如下:

npm install

运行以下代码:

npm run numbers

给出以下结果:

Functional Programming in TypeScript

补充

Functional Programming in TypeScript

设E和F是两个集合。 E 中 F 的相对补,记为 E F 是属于 E 成员但不属于 F 成员的所有元素的集合。

设补码为相对补运算。因此,补码操作可以在 TypeScript 中实现如下:

npm run plane
运行下面的代码:
npm run fractals

给出以下结果:

Functional Programming in TypeScript

对称差

Functional Programming in TypeScript

设E和F是两个集合。 E 和 F 的对称差,用 E Δ F 表示,是属于 E 和 F 的成员但不在 E 和 F 交集内的所有元素的集合。

设 SymmetricDifference 为 对称差 运算。因此,SymmetricDifference 操作可以在 TypeScript 中通过两种方式实现。一种简单的方法是使用并集和补集运算,如下所示:

S'(x) = true if x is in S'
S'(x) = false if x is not in S'

另一种方法是使用 XOR 二元运算,如下所示:

S'(a) = S'(b) = true
S'(c) = S'(d) = false

运行以下代码:

S'(a) = S'(b) = true
S'(c) = S'(d) = false

给出以下结果:

Functional Programming in TypeScript

其他操作

本节介绍了集合上其他有用的二元运算。

包含

设 Contains 为检查元素是否在集合中的操作。此操作是一个函数,它接受一个元素作为参数,如果该元素在集合中则返回 true,否则返回 false。

因此,该操作在 TypeScript 中定义如下:

type Set<T> = (x: T) => boolean

因此,运行以下代码:

npm install

给出以下结果:

Functional Programming in TypeScript

添加

设 Add 为将元素添加到集合中的操作。此操作是一个函数,它将一个元素作为参数并将其添加到集合中。

因此,该操作在 TypeScript 中定义如下:

npm run numbers

因此,运行以下代码:

npm run plane

给出以下结果:

Functional Programming in TypeScript

消除

设Remove为从集合中删除元素的操作。此操作是一个函数,它将一个元素作为参数并将其从集合中删除。

因此,该操作在 TypeScript 中定义如下:

npm run fractals

因此,运行以下代码:

S'(x) = true if x is in S'
S'(x) = false if x is not in S'

给出以下结果:

Functional Programming in TypeScript

对于那些想走得更远的人

你可以看到我们通过函数式编程在 TypeScript 中做一些集合代数是多么容易。前面的部分显示了最基本的定义。但是,如果你想更进一步,你可以考虑:

  • 集合上的关系
  • 抽象代数,如幺半群、群、域、环、K-向量空间等
  • 包含排除原则
  • 罗素悖论
  • 康托悖论
  • 对偶向量空间
  • 定理和推论

欧几里得平面

在上一节中,集合的基本概念是在 TypeScript 中实现的。在本节中,我们将练习在欧几里得平面上实现的概念。

绘制圆盘

Functional Programming in TypeScript

圆盘是由圆包围的平面的子集。有两种类型的磁盘。 圆盘是包含构成其边界的圆的点的圆盘,圆盘是不包含构成其边界的圆的点的圆盘。

在本节中,我们将设置封闭圆盘的特征函数并将其绘制在HTML5页面中。

要设置特征函数,我们首先需要一个计算平面上两点之间的欧氏距离的函数。该函数的实现如下:

S'(a) = S'(b) = true
S'(c) = S'(d) = false

其中 Point 定义如下:

S'(a) = S'(b) = true
S'(c) = S'(d) = false

这个公式基于毕达哥拉斯定理。

Functional Programming in TypeScript

其中 c 是 欧几里得距离,a² 是 (p1.X - p2.X)²,b² 是 (p1.Y - p2.Y)²。

设Disk为闭盘的特征函数。在集合代数中,实数集中闭盘的定义如下:

Functional Programming in TypeScript

其中 a 和 b 是中心坐标,R 是半径。

因此,Disk 在 TypeScript 中的实现如下:

npm install

为了在 HTML5 页面中查看集合,我决定实现一个在 欧几里得平面 中绘制集合的函数draw。我选择了HTML5,因此使用canvas元素进行绘图。

因此,我通过绘制方法构建了如下所示的欧几里得平面

Functional Programming in TypeScript

下面执行平面。

npm run numbers

在绘制函数中,创建了一个与欧几里得平面容器具有相同宽度和相同高度的画布。然后,如果画布的像素 (x,y) 中的每个点属于该集合,则该点将被替换为黑点。 xMin、xMax、yMin 和 yMax 是上面欧几里得平面图中所示的边界值。

运行以下代码:

npm run plane

其中disk是画布的id:

npm run fractals

给出以下结果:

Functional Programming in TypeScript

绘制水平和垂直半平面

Functional Programming in TypeScript

水平垂直半平面是平面将欧几里得空间划分成的两个子集之一。 水平半平面是两个子集之一,平面通过与Y轴垂直的线将欧几里得空间划分为两个子集,如上图所示。 垂直半平面是平面通过与X轴垂直的线将欧几里得空间划分成的两个子集之一。

本节我们将设置水平垂直半平面的特征函数,将它们绘制在HTML5页面中,看看会发生什么如果我们将它们与 disk 子集结合起来,我们就可以做到。

设 Horizo​​ntalHalfPlane 为 水平半平面的特征函数。 Horizo​​ntalHalfPlane 在 TypeScript 中的实现如下:

S'(x) = true if x is in S'
S'(x) = false if x is not in S'

因此,运行以下代码:

npm install

其中 hhp 是画布的 id:

npm run numbers

给出以下结果:

Functional Programming in TypeScript

设VerticalHalfPlane为垂直半平面的特征函数。 VerticalHalfPlane 在 TypeScript 中的实现如下:

npm run plane
因此,运行以下代码:
npm run fractals

其中 vhd 是画布的 id:

S'(x) = true if x is in S'
S'(x) = false if x is not in S'

给出以下结果:

Functional Programming in TypeScript

在文章的第一部分中,我们在集合上设置了基本的二元运算。因此,例如,通过组合圆盘和半平面的交集,我们可以绘制半圆盘子集。

因此,运行以下示例:

S'(a) = S'(b) = true
S'(c) = S'(d) = false

其中 hd 是画布的 id:

S'(a) = S'(b) = true
S'(c) = S'(d) = false

给出以下结果:

Functional Programming in TypeScript

功能

本节介绍欧几里得平面上的集合上的函数。

翻译

Functional Programming in TypeScript

令translatePoint 为平移平面上的点的函数。在欧几里得几何中,translatePoint 是一个将给定点沿指定方向移动恒定距离的函数。因此 TypeScript 中的实现如下:

type Set<T> = (x: T) => boolean

其中 (deltax, deltay) 是平移的常数向量。

设translate为在平面上平移集合的函数。该函数在 TypeScript 中简单实现如下:

Empty(x) = false if x is in E
Empty(x) = false if x is not in E
“translate”采用参数“deltax”和“deltay”作为参数,“deltax”是第一欧几里德维度中的增量距离,“deltay”是第二欧几里德维度中的增量距离。如果点 _P (x, y)_ 在集合 _S_ 中平移,则其坐标将更改为 _(x', y') = (x, delatx, y, deltay)_。因此,点 _(x' - delatx, y' - deltay)_ 将始终属于集合 _S_。在集合代数中,“平移”被称为同构,换句话说,所有平移的集合形成_平移群T_,它与空间本身同构。这就解释了该函数的主要逻辑。 因此,在 HTML5 页面中运行以下代码:
const empty = () => (e: T) => false

其中 ep_op 是画布的 id:

console.log('\nEmpty set:')
console.log('Is 7 in {}?', common.empty()(7))

给出以下结果:

Functional Programming in TypeScript

同调

Functional Programming in TypeScript

设scalePoint为将任意点M发送到另一个点N的函数,使得线段SNSM在同一行,但按因子 λ 缩放。在集合代数中,尺度的公式如下:

Functional Programming in TypeScript

因此 TypeScript 中的实现如下:

npm install

其中 (deltax, deltay) 是平移的常数向量,(lambdax, lambdaday) 是 lambda 向量。

设标度为对计划中的集合应用相似性的函数。该函数在 TypeScript 中简单实现如下:

npm run numbers

scale 将第一欧几里得维度中的增量距离 deltax、第二欧几里得维度中的增量距离 deltay 以及常数因子向量 λ (lambdax, lambdaday) 作为参数。如果一个点 P (x, y) 在集合 S 中进行尺度变换,那么它的坐标将变为 (x', y') = (lambdax * x、delatx、lambda * y、deltay)。因此,点 ((x'- delatx)/lambdax, (y' - deltay)/lambday) 将始终属于集合 S,如果 lambda 与向量不同0,当然。在集合代数中,尺度被称为同构,换句话说,所有同势的集合形成同势群H,它与空间本身{0}同构。这就解释了该函数的主要逻辑。

因此,在我们的 HTML5 页面中运行以下代码:

npm run plane

给出以下结果:

Functional Programming in TypeScript

旋转

Functional Programming in TypeScript

令rotatePoint为以角度θ旋转点的函数。在矩阵代数中,rotatePoint 的公式如下:

Functional Programming in TypeScript

其中(x', y')是旋转后点的坐标,x'y'的公式为如下:

Functional Programming in TypeScript

这个公式的演示非常简单。看看这个轮换。

Functional Programming in TypeScript

演示如下:

Functional Programming in TypeScript

因此 TypeScript 中的实现如下:

npm install

设rotate为对平面内的集合应用角度θ旋转的函数。该函数在 TypeScript 中简单实现如下。

npm run numbers

rotate 是一个以 theta 为参数的函数,theta 是旋转的角度。如果一个点 P (x, y) 在集合 S 中进行旋转变换,则其坐标将变为 (x', y') = (x * cos(theta) - y * sin(theta), x * sin(theta), y * cos(theta))。因此,点 (x' * cos(theta), y' * sin(theta), y' * cos(theta) - x' * sin(theta)) 将始终属于集合 S。在集合代数中,旋转被称为同构,换句话说,所有旋转的集合形成旋转群R,它与空间本身同构。这就解释了该函数的主要逻辑。

因此,在我们的 HTML5 页面中运行以下代码:

npm run plane

给出以下结果:

Functional Programming in TypeScript

对于那些想走得更远的人

很简单,不是吗?对于那些想要更进一步的人,您可以探索这些:

  • 椭圆
  • 三维欧几里得空间
  • 椭圆体
  • 抛物面
  • 双曲面
  • 球谐函数
  • 超椭球
  • 豪美亚
  • 同形体
  • Focaloid

分形

Functional Programming in TypeScript

分形是分形维数通常超过其拓扑维数并且可能落在整数之间的集合。例如,Mandelbrot 集合是由一系列复杂二次多项式定义的分形:

npm run fractals

其中 c 是复数。 Mandelbrot 分形被定义为所有点 c 的集合,使得上述序列不会逃逸到无穷大。在集合代数中,其公式如下:

Functional Programming in TypeScript

分形(抽象数据类型)在 TypeScript 中始终可以表示如下:

S'(x) = true if x is in S'
S'(x) = false if x is not in S'

复数和绘图

为了能够绘制分形,我需要操纵复数数字。因此,我创建了下面的 Complex 类:

S'(a) = S'(b) = true
S'(c) = S'(d) = false

曼德尔布罗分形

我创建了一个 Mandelbrot 分形(抽象数据类型表示)P(z) = z^2 c,如下所示。

npm install
为了能够绘制_Complex_数字,我创建了一个“ComplexPlane”类。下面是 TypeScript 中的实现。
npm run numbers

因此,运行以下代码:

npm run plane

其中 fractal 是画布的 id:

npm run fractals

给出以下结果:

Functional Programming in TypeScript

对于那些想走得更远的人

对于那些想要更进一步的人,您可以探索这些:

  • 牛顿分形
  • 朱莉娅分形
  • 其他分形

就是这样!我希望你喜欢阅读。

以上是TypeScript 中的函数式编程的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn