首頁  >  文章  >  web前端  >  TypeScript 中的函數式編程

TypeScript 中的函數式編程

Patricia Arquette
Patricia Arquette原創
2024-10-19 22:32:29697瀏覽

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 環境並使用以下命令安裝所有必需的依賴項:

要執行數字的演示,請執行以下命令:

要運行歐幾里德平面的演示,請執行以下命令:

要執行分形演示,請執行以下命令:

透過函數表示數據

設S 為任意元素a、b、c ... 的集合(例如,桌子上的書或歐幾里德平面上的點),並設S' 為這些元素的任意子集(例如,桌上的綠色書籍或以歐幾里德平面原點為圓心的半徑為1 的圓中的點)。

集合 S' 的特徵函數 S'(x) 是將 S 的每個元素 x 與 true 或 false 相關聯的函數。

令 S 為桌上的一套書,讓 S' 為桌上的一套綠書。設a和b是桌上的兩本綠書,c和d是桌上的兩本紅書。然後:

設 S 為歐幾里德平面中點的集合,設 S' 為以歐幾里德平面原點 (0, 0)(單位圓)為中心、半徑為 1 的圓中點的集合。設a和b為單位圓中的兩點,c和d為以歐幾里德平面原點為圓心、半徑為2的圓中的兩點。然後:

因此,任何集合S'總是可以用它的特徵函數來表示。此函數接受一個元素作為參數,如果該元素位於 S' 中,則傳回 true,否則傳回 false。換句話說,集合(抽象資料型別)可以透過 TypeScript 中的函數來表示。

在接下來的部分中,我們將了解如何透過 TypeScript 以函數式方式表示集合代數中的一些基本集合,然後我們將定義集合上的通用二元運算。然後,我們將這些運算應用於數字,然後應用於歐幾里德平面的子集。集合是抽象資料結構,數字的子集和歐幾里德平面的子集是抽象資料結構的表示,最後的二元運算是適用於抽象資料結構的任何表示的通用邏輯。

本節介紹集合代數中一些基本集合透過 TypeScript 的表示。

空集合

Functional Programming in TypeScript

設E為空集,並清空其特徵函數。在集合代數中,E 是沒有元素的唯一集合。因此,Empty 可以定義如下:

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

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

Functional Programming in TypeScript

因此,執行以下程式碼:

給出以下結果:

Functional Programming in TypeScript

全部設定

Functional Programming in TypeScript

設 S 為集合,S' 為包含所有元素及其所有 特徵函數 的 S 子集。在集合代數中,S' 是包含所有元素的完整集合。因此,All 可以這樣定義:

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

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

Functional Programming in TypeScript

因此,執行以下程式碼:

給出以下結果:

Functional Programming in TypeScript

單例集

設 E 為 Singleton 集合,Singleton 為其特徵函數。在集合代數中,E 也稱為單位集或一元組,是只有一個元素 e 的集合。因此,Singleton可以定義如下:

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

因此,執行以下程式碼:

給出以下結果:

Functional Programming in TypeScript

其他套裝

本節介紹整數集的子集。

偶數

設E是偶數集合,Even是它的特徵函數。在數學中,偶數是二的倍數。因此,Even 可以定義如下:

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

因此,執行以下程式碼:

給出以下結果:

Functional Programming in TypeScript

奇數

設E為奇數集合,Odd為其特徵函數。在數學中,奇數是指不是二的倍數的數。因此,Odd 可以定義如下:

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

因此,執行以下程式碼:

給出以下結果:

Functional Programming in TypeScript

3的倍數

設 E 為 3 的倍數集,MultipleOfThree 是其特徵函數。在數學中,3的倍數是能被3整除的數。因此,MultipleOfThree可以定義如下:

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

因此,執行以下程式碼:

給出以下結果:

Functional Programming in TypeScript

5的倍數

設 E 為 5 的倍數集,MultipleOfFive 為其特徵函數。在數學中,5的倍數是能被5整除的數。因此,MultipleOfFive可以定義如下:

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

因此,執行以下程式碼:

給出以下結果:

Functional Programming in TypeScript

質數

很久以前,當我在玩 Project Euler 問題時,我必須解決以下問題:

為了解決這個問題,我必須先寫一個快速演算法來檢查給定的數字是否是質數。演算法寫完後,我寫了一個迭代演算法,迭代質數,直到找到第 10 001 個質數。

設 E 為素數集,並素其特徵函數。在數學中,質數是大於 1 的自然數,除了 1 和它本身之外沒有正因數。因此,Prime可以定義如下:

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

因此,運行下面的程式碼來解決我們的問題:

其中 getPrime 定義如下:

給出以下結果:

Functional Programming in TypeScript

二元運算

本節介紹了從給定集合構造新集合和操作集合的幾個基本操作。下面是集合代數中的文氏圖。

Functional Programming in TypeScript

聯盟

Functional Programming in TypeScript

設E和F是兩個集合。 E 和 F 的,以 E U F 表示,是屬於 E 和 F 的成員的所有元素的集合。

讓 Union 成為 並集 操作。因此,Union 操作可以在 TypeScript 中實作如下:

執行以下程式碼:

給出以下結果:

Functional Programming in TypeScript

路口

Functional Programming in TypeScript

設E和F是兩個集合。 E 和 F 的交集,以 E n F 表示,是同時屬於 E 和 F 成員的所有元素的集合。

設 Intersection 為 交集 運算。因此,Intersection 操作可以在 TypeScript 中實作如下:

執行以下程式碼:

給出以下結果:

Functional Programming in TypeScript

笛卡兒積

Functional Programming in TypeScript

設E和F是兩個集合。 E 和 F 的笛卡爾積,用 E × F 表示,是所有有序對 (e, f) 的集合,使得 e 是 E 的成員,f 是 F 的成員。

設 CartesianProduct 為 笛卡爾積 運算。因此,CartesianProduct 運算可以在 TypeScript 中實作如下:

執行以下程式碼:

給出以下結果:

Functional Programming in TypeScript

補充

Functional Programming in TypeScript

設E和F是兩個集合。 E 中 F 的相對補,記為 E F 是屬於 E 成員但不屬於 F 成員的所有元素的集合。

設補碼為相對補運算。因此,補碼操作可以在 TypeScript 中實作如下:

運行下面的程式碼:

給出以下結果:

Functional Programming in TypeScript

對稱差

Functional Programming in TypeScript

設E和F是兩個集合。 E 和 F 的對稱差,以 E Δ F 表示,是屬於 E 和 F 的成員但不在 E 和 F 交集內的所有元素的集合。

設 SymmetricDifference 為 對稱差 運算。因此,SymmetricDifference 操作可以在 TypeScript 中透過兩種方式實現。一個簡單的方法是使用並集和補集運算,如下所示:

另一種方法是使用 XOR 二元運算,如下:

執行以下程式碼:

給出以下結果:

Functional Programming in TypeScript

其他操作

本節介紹了集合上其他有用的二元運算。

包含

設 Contains 為檢查元素是否在集合中的運算。此操作是一個函數,它接受一個元素作為參數,如果該元素在集合中則傳回 true,否則傳回 false。

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

因此,執行以下程式碼:

給出以下結果:

Functional Programming in TypeScript

添加

設 Add 為將元素加入集合中的運算。此操作是一個函數,它將一個元素作為參數並將其添加到集合中。

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

因此,執行以下程式碼:

給出以下結果:

Functional Programming in TypeScript

消除

設Remove為從集合中刪除元素的運算。此操作是一個函數,它將一個元素作為參數並將其從集合中刪除。

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

因此,執行以下程式碼:

給出以下結果:

Functional Programming in TypeScript

對於那些想走得更遠的人

你可以看到我們透過函數式程式設計在 TypeScript 中做一些集合代數是多麼容易。前面的部分顯示了最基本的定義。但是,如果你想更進一步,你可以考慮:

  • 集合上的關係
  • 抽象代數,如么半群、群、域、環、K-向量空間等
  • 包含排除原則
  • 羅素悖論
  • 康托悖論
  • 對偶向量空間
  • 定理與推論

歐幾里德平面

在上一節中,集合的基本概念是在 TypeScript 中實現的。在本節中,我們將練習在歐幾裡得平面上實現的概念。

繪製圓盤

Functional Programming in TypeScript

圓盤是由圓包圍的平面的子集。有兩種類型的磁碟。 圓盤是包含構成其邊界的圓的點的圓盤,圓盤是不包含構成其邊界的圓的點的圓盤。

在本節中,我們將設定封閉圓盤的特徵函數並將其繪製在HTML5頁面中。

要設定特徵函數,我們首先需要一個計算平面上兩點之間的歐氏距離的函數。此函數的實作如下:

其中 Point 定義如下:

這個公式是基於畢達哥拉斯定理。

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 中的實作如下:

為了在 HTML5 頁面中查看集合,我決定實作一個在 歐幾里德平面 中繪製集合的函數draw。我選擇了HTML5,因此使用canvas元素進行繪圖。

因此,我透過繪製方法建構瞭如下所示的歐幾里德平面

Functional Programming in TypeScript

下面執行平面。

在繪製函數中,創建了一個與歐幾里德平面容器具有相同寬度和相同高度的畫布。然後,如果畫布的像素 (x,y) 中的每個點屬於該集合,則該點將被替換為黑點。 xMin、xMax、yMin 和 yMax 是上面歐幾里德平面圖中所示的邊界值。

執行以下程式碼:

其中disk是畫布的id:

給出以下結果:

Functional Programming in TypeScript

繪製水平和垂直半平面

Functional Programming in TypeScript

水平垂直半平面是平面將歐幾里德空間分割成的兩個子集之一。 水平半平面是兩個子集之一,平面透過與Y軸垂直的線將歐幾里德空間劃分為兩個子集,如上圖所示。 垂直半平面是平面通過與X軸垂直的線將歐幾里德空間劃分成的兩個子集之一。

本節我們將設定水平垂直半平面的特徵函數,將它們繪製在HTML5頁面中,看看會發生什麼如果我們將它們與disk 子集結合起來,我們就可以做到。

設 Horizo​​ntalHalfPlane 為 水平半平面的特徵函數。 Horizo​​ntalHalfPlane 在 TypeScript 中的實作如下:

因此,執行以下程式碼:

其中 hhp 是畫布的 id:

給出以下結果:

Functional Programming in TypeScript

設VerticalHalfPlane為垂直半平面的特徵函數。 VerticalHalfPlane 在 TypeScript 中的實作如下:

因此,運行以下程式碼:

其中 vhd 是畫布的 id:

給出以下結果:

Functional Programming in TypeScript

在文章的第一部分中,我們在集合上設定了基本的二元運算。因此,例如,透過組合圓盤和半平面的交集,我們可以繪製半圓盤集合。

因此,執行以下範例:

其中 hd 是畫布的 id:

給出以下結果:

Functional Programming in TypeScript

功能

本節介紹歐幾裡得平面上的集合上的函數。

翻譯

Functional Programming in TypeScript

令translatePoint 為平移平面上的點的函數。在歐幾里德幾何中,translatePoint 是一個將給定點沿著指定方向移動恆定距離的函數。因此 TypeScript 中的實作如下:

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

設translate為在平面上平移集合的函數。此函數在 TypeScript 中簡單實作如下:

「translate」採用參數「deltax」和「deltay」作為參數,「deltax」是第一歐幾里德維度中的增量距離,而「deltay」是第二歐幾里德維度中的增量距離。如果點 _P (x, y)_ 在集合 _S_ 中平移,則其座標將改為 _(x', y') = (x, delatx, y, deltay)_。因此,點 _(x' - delatx, y' - deltay)_ 將永遠屬於集合 _S_。在集合代數中,「平移」稱為同構,換句話說,所有平移的集合形成_平移群T_,它與空間本身同構。這就解釋了該函數的主要邏輯。 因此,在 HTML5 頁面中執行以下程式碼:

其中 ep_op 是畫布的 id:

給出以下結果:

Functional Programming in TypeScript

同調

Functional Programming in TypeScript

設scalePoint為將任意點M送到另一個點N的函數,使得線段SNSM在同一行,但依因子λ 縮放。在集合代數中,尺度的公式如下:

Functional Programming in TypeScript

因此 TypeScript 中的實作如下:

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

設標度為對計畫中的集合應用相似性的函數。此函數在 TypeScript 中簡單實作如下:

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 頁面中執行以下程式碼:

給出以下結果:

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 中的實作如下:

設rotate為對平面內的集合套用角度θ旋轉的函數。此函數在 TypeScript 中簡單實作如下。

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 頁面中執行以下程式碼:

給出以下結果:

Functional Programming in TypeScript

對於那些想走得更遠的人

很簡單,不是嗎?對於那些想要更進一步的人,您可以探索這些:

  • 橢圓
  • 三維歐幾裡得空間
  • 橢圓體
  • 拋物面
  • 雙曲面
  • 球諧函數
  • 超橢球
  • 豪美亞
  • 同形體
  • Focaloid

分形

Functional Programming in TypeScript

分形是分形維數通常超過其拓撲維數並且可能落在整數之間的集合。例如,Mandelbrot 集合是由一系列複雜二次多項式定義的分形:

其中 c 是複數。 Mandelbrot 分形被定義為所有點 c 的集合,使得上述序列不會逃逸到無限大。在集合代數中,其公式如下:

Functional Programming in TypeScript

分形(抽象資料型別)在 TypeScript 中始終可以表示如下:

複數和繪圖

為了能夠繪製分形,我需要操縱複數數字。因此,我創建了下面的 Complex 類別:

曼德布羅分形

我建立了一個 Mandelbrot 分形(抽象資料型別表示)P(z) = z^2 c,如下所示。

為了能夠繪製_Complex_數字,我建立了一個「ComplexPlane」類別。下面是 TypeScript 中的實作。

因此,執行以下程式碼:

其中 fractal 是畫布的 id:

給出以下結果:

Functional Programming in TypeScript

對於那些想走得更遠的人

對於那些想要更進一步的人,您可以探索這些:

  • 牛頓分形
  • 茱莉亞分形
  • 其他分形

就是這樣!我希望你喜歡閱讀。

以上是TypeScript 中的函數式編程的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn