ホームページ  >  記事  >  ウェブフロントエンド  >  TypeScript での関数型プログラミング

TypeScript での関数型プログラミング

Patricia Arquette
Patricia Arquetteオリジナル
2024-10-19 22:32:29575ブラウズ

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

Numbers のデモを実行するには、次のコマンドを実行します:

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 をテーブル上の 2 冊の緑の本、c と d を 2 冊の赤い本としましょう。次に:

npm install

S をユークリッド平面内の点の集合、S' をユークリッド平面の原点 (0, 0) を中心とする半径 1 の円 (単位円) 内の点の集合とする。 a と b を単位円内の 2 点とし、c と d をユークリッド平面の原点を中心とする半径 2 の円内の 2 点としましょう。次に:

npm run numbers

したがって、任意の集合 S' は常にその 特性関数 によって表すことができます。要素を引数として受け取り、この要素が S' にある場合は true、それ以外の場合は false を返す関数。つまり、セット (抽象データ型) は TypeScript の関数を通じて表現できます。

npm run plane

次のセクションでは、TypeScript を使用して関数的な方法で集合の代数におけるいくつかの基本的な集合を表現する方法を見てから、集合に対する一般的な二項演算を定義します。次に、これらの操作を数値に適用し、次にユークリッド平面のサブセットに適用します。セットは抽象データ構造であり、数値のサブセットとユークリッド平面のサブセットは抽象データ構造の表現であり、最後に二項演算は抽象データ構造のあらゆる表現で動作する汎用ロジックです。

セット

このセクションでは、TypeScript を使用した集合の代数におけるいくつかの基本的な集合の表現を紹介します。

空の集合

Functional Programming in TypeScript

E を空集合とし、その 特性関数を空にします。集合の代数では、E は要素を持たない一意の集合です。したがって、Empty は次のように定義できます。

npm run fractals

したがって、TypeScript での E の表現は次のように定義できます。

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

は次の結果を返します:

Functional Programming in TypeScript

すべてを設定

Functional Programming in TypeScript

S を集合、S' をすべての要素とそのすべての 特性関数 を含む S の部分集合とします。集合の代数では、S' はすべての要素を含む完全な集合です。したがって、All は次のように定義できます。

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

したがって、TypeScript での S' の表現は次のように定義できます。

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

集合の代数では、All は次のように表されます。

Functional Programming in TypeScript

したがって、以下のコードを実行します:

npm install

は次の結果を返します:

Functional Programming in TypeScript

シングルトンセット

E をシングルトン集合とし、シングルトンをその 特性関数 とします。集合の代数では、単位集合または 1 タプルとしても知られる E は、要素 e を 1 つだけ持つ集合です。したがって、シングルトンは次のように定義できます。

npm run numbers

したがって、TypeScript での E の表現は次のように定義できます。

npm run plane

したがって、以下のコードを実行します:

npm run fractals

は次の結果を返します:

Functional Programming in TypeScript

その他のセット

このセクションでは、整数セットのサブセットを示します。

丁数

E を偶数の集合とし、その 特性関数を偶数とします。数学では、偶数は 2 の倍数です。したがって、偶数は次のように定義できます。

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

したがって、TypeScript での E の表現は次のように定義できます。

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 を奇数の集合とし、奇数をその 特性関数 とします。数学では、奇数は 2 の倍数ではない数です。したがって、Odd は次のように定義できます。

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

したがって、TypeScript での E の表現は次のように定義できます。

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))

したがって、TypeScript での E の表現は次のように定義できます。

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

したがって、TypeScript での E の表現は次のように定義できます。

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'

したがって、TypeScript での E の表現は次のように定義できます。

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 を 2 つのセットとする。 E U F で示される E と F の 和集合 は、E と F のいずれかのメンバーであるすべての要素のセットです。

Union を 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 を 2 つのセットとする。 E と F の 交差 (E n F で示される) は、E と F の両方のメンバーであるすべての要素のセットです。

Intersection を 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 を 2 つのセットとする。 E × F で示される E と F のデカルト積は、e が E のメンバーであり、f が F のメンバーであるような、すべての順序ペア (e, f) の集合です。

CartesianProduct を デカルト積 演算とします。したがって、CartesianProduct 演算は TypeScript で次のように実装できます。

npm install

以下のコードを実行します:

npm run numbers

は次の結果を返します:

Functional Programming in TypeScript

補完物

Functional Programming in TypeScript

E と F を 2 つのセットとする。 E における F の 相対補体 (EF で示されます) F は、E のメンバーであるが F のメンバーではないすべての要素の集合です。

Complement を 相対補数 演算とします。したがって、Complement 操作は TypeScript で次のように実装できます。

npm run plane
以下のコードを実行します。
npm run fractals

は次の結果を返します:

Functional Programming in TypeScript

対称的な差異

Functional Programming in TypeScript

E と F を 2 つのセットとする。 E Δ F で示される E と F の対称差は、E と F のいずれかのメンバーであるが、E と F の共通部分には含まれないすべての要素の集合です。

SymmetricDifference を 対称差分 演算とします。したがって、SymmetricDifference 操作は TypeScript で 2 つの方法で実装できます。簡単な方法は、次のように結合演算と補数演算を使用することです:

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

もう 1 つの方法は、次のように 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

ディスクは、円で囲まれた平面のサブセットです。ディスクには2種類あります。 閉じたディスクは、その境界を構成する円の点を含むディスクであり、開いたディスクは、その境界を構成する円の点を含まないディスクです。

このセクションでは、Closed ディスクの 特徴関数 を設定し、HTML5 ページに描画します。

特性関数を設定するには、まず平面内の 2 点間のユークリッド距離を計算する関数が必要です。この関数は次のように実装されます:

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 は半径です。

したがって、TypeScript での Disk の実装は次のようになります:

npm install

HTML5 ページでセットを表示するために、ユークリッド平面でセットを描画する関数描画を実装することにしました。 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

水平 または 垂直 半平面は、平面がユークリッド空間を分割する 2 つの部分集合のいずれかです。 水平半平面は、上の図のように、Y 軸に垂直な線を通してユークリッド空間を分割する 2 つのサブセットのいずれかです。 垂直半平面は、X 軸に垂直な線を通してユークリッド空間を分割する平面の 2 つのサブセットのいずれかです。

このセクションでは、水平垂直 の半面の 特徴的な関数 を設定し、HTML5 ページに描画して、どのような機能があるかを確認します。これらを ディスク サブセットと組み合わせれば可能です。

horizo​​ntalHalfPlane を 水平 半平面の 特性関数 とします。 TypeScript での horizo​​ntalHalfPlane の実装は次のとおりです:

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 を 垂直 半平面の 特性関数 とします。 TypeScriptでのVerticalHalfPlaneの実装は次のとおりです:

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` と 2 番目のユークリッド次元のデルタ距離である `deltay` をパラメータとして受け取ります。点 _P (x, y)_ がセット _S_ 内で変換される場合、その座標は _(x', y') = (x, delatx, y, deltay)_ に変わります。したがって、点 _(x' - delatx, y' - deltay)_ は常に集合 _S_ に属します。集合代数では、「翻訳」は同型と呼ばれます。言い換えれば、すべての翻訳の集合は、空間自体と同型である _translation グループ 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 を、セグメント SNSM と同じ線上になるように、任意の点 M を別の点 N に送信する関数とします。 ですが、係数 λ でスケーリングされます。集合の代数では、スケールは次のように定式化されます:

Functional Programming in TypeScript

したがって、TypeScript での実装は次のようになります:

npm install

ここで、(deltax, deltay) は平行移動の定数ベクトル、(lambdax, lambday) はラムダ ベクトルです。

スケールを計画内のセットに相等性を適用する関数とします。この関数は、TypeScript で次のように単純に実装されます。

npm run numbers

scale は、最初のユークリッド次元のデルタ距離である deltax、2 番目のユークリッド次元のデルタ距離である deltay、および定数因子ベクトル λ である (lambdax, lambday) をパラメーターとして受け取ります。点 P (x, y) が集合 S のスケールを介して変換される場合、その座標は (x', y') = (lambdax *) に変わります。 x、delatx、lambday * y、deltay)。したがって、点 ((x'- delatx)/lambdax, (y' - deltay)/lambday) は、ラムダがベクトルと異なる場合、常に集合 S に属します。もちろん0です。集合の代数では、スケールは同型と呼ばれます。言い換えれば、すべての相同性の集合は、空間自体 {0} と同型である 相同群 H を形成します。これは関数の主なロジックを説明しています。

したがって、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

角度 θ の平面内のセットに回転を適用する関数を回転とします。この関数は TypeScript で次のように単純に実装されます。

npm run numbers

rotate は、回転角度である theta をパラメータとして取る関数です。点 P (x, y) がセット S 内で回転によって変換される場合、その座標は (x', y') = (x * cos(シータ) - y * sin(シータ)、x * sin(シータ)、y * cos(シータ))。したがって、点 (x' * cos(theta), y' * sin(theta), y' * cos(theta) - x' * sin(theta)) は常に集合 す。集合の代数では、回転は同型と呼ばれます。言い換えれば、すべての回転の集合は、空間自体と同型である 回転群 R を形成します。これは関数の主なロジックを説明しています。

したがって、HTML5 ページで以下のコードを実行します。

npm run plane
は次の結果を返します:

Functional Programming in TypeScript

さらに上を目指したい人へ

とてもシンプルですね。さらに詳しく知りたい方は、以下をご覧ください:

    楕円
  • 3次元ユークリッド空間
  • 楕円体
  • 放物面
  • 双曲面
  • 球面調和関数
  • 超楕円体
  • ハウメア
  • ホメオイド
  • フォーカロイド
フラクタル

Functional Programming in TypeScript

フラクタルは、通常は位相次元を超え、整数の間に入る可能性があるフラクタル次元を持つ集合です。たとえば、

マンデルブロ セットは、複素 2 次多項式の族によって定義されるフラクタルです。

npm run fractals
ここで、c は複合体です。

マンデルブロ フラクタルは、上記の数列が無限に逃げないように、すべての点 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
マンデルブロ フラクタル

私は

マンデルブロ フラクタル (抽象データ型表現) P(z) = z^2 c を作成しました。これは以下で利用可能です。

npm install
_Complex_ 数値を描画できるようにするために、`ComplexPlane` クラスを作成しました。以下はTypeScriptでの実装です。
npm run numbers

したがって、以下のコードを実行します:

npm run plane

ここで、フラクタルはキャンバスの ID です:

npm run fractals

は次の結果を返します:

Functional Programming in TypeScript

さらに上を目指したい人へ

さらに詳しく知りたい方は、以下をご覧ください:

  • ニュートン フラクタル
  • ジュリア フラクタル
  • その他のフラクタル

それだけです!楽しんで読んでいただければ幸いです。

以上がTypeScript での関数型プログラミングの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。