JavaScriptに基づくいくつかの関数式プログラミング概念の解説


元の住所の翻訳者のGithubシリーズの文章の住所は本文の元の作者はまだ全部完成していないで、興味があるのは原文あるいは翻訳の住所まで更新に関心を持つことができます.
Funtional Programming Jargon:関数式プログラミング用語解釈
本論文の主な目的は、関数式プログラミングにおいてよく見られる理論用語概念を分かりやすく説明することです.
Arty:パラメータ数
Arityは、unary、binary、ternaryなどの関数のパラメータ数を指し、2つの接尾辞-ary-ityから構成される.例えば、一つの関数が二つのパラメータを入力できるなら、いわゆるbinary function(二元関数)または一つは二つのパラメータの関数と呼ばれます.このような関数はラテン語が好きな人に「dddyadic(二価の)」関数と呼ばれることもあります.このように類推すると、不定パラメータの方程式はvariadic( )と呼ばれる.
const sum = (a, b) => a + b;

const arity = sum.length;
console.log(arity);
// => 2
// The arity of sum is 2
Higher-Order Functions(HOF):高等関数
ある関数を受信して、パラメータの関数として、関数を返しても別のタイプに戻ることができる関数を選択します.
const filter = (pred, xs) => {
  const result = [];
  for (var idx = 0; idx < xs.length; idx += 1) {
    if (pred(xs[idx])) {
      result.push(xs[idx]);
    }
  }
  return result;
};
const is = type => x => Object(x) instanceof type;
filter(is(Number), [0, '1', 2, null]); //=> [0, 2]
Partial Application:ローカルパッケージ
本来の多参値の関数を固定パラメータ数の関数としてパッケージ化するプロセスをPartial Appliationと呼びます.
let sum = (a, b) => a + b;

// partially applying `a` to `40`
let partial = sum.bind(null, 40);

// Invoking it with `b`
partial(2); //=> 42
Currying
Nパラメータ値の関数をN個の一要素関数の組み合わせに変換します.CurrryingとPartial Appliationの違いは、Partial Appplicationが最終的に生成した関数が複数の値を受信することができます.Curryingが生成した関数シーケンスの各関数は一つのパラメータしか受信できません.
let sum = (a, b) => a + b;

let curriedSum = (a) => (b) => a + b;

curriedSum(40)(2) // 42.
Compsition:コンビネーション
デザインモードのDecoratorのような感じがします.つまり、二つの指定されたタイプの組み合わせを一つの新しい値の関数に変えることができます.
最も一般的な組み合わせは、一般的な関数の組み合わせであり、異なる関数を単一の値を返す関数に組み合わせることができます.
const compose = (f, g) => a => f(g(a)) // Definition
const floorAndToString = compose((val)=> val.toString(), Math.floor) //Usage
floorAndToString(121.212121) // "121"
ピューリティ:純関数
一つは副作用がなく、戻り値は入力によって決まる関数だけが純関数になります.
let greet = "yo";

greet.toUpperCase(); // YO;

greet // yo;
As opposed to:
let numbers = [1, 2, 3];

numbers.splice(0); // [1, 2, 3]

numbers // []
Side effects:副作用
関数の場合、戻り値以外にも何らかの他の状態を修正したり、外部関数などと観測可能なインタラクションがあります.
console.log("IO is a side effect!");
Idempotency:べき乗等性
複数回実行しても副作用が発生しない関数を、べき乗などの関数と呼びます.f(f(x)) = f(x)Math.abs(Math.abs(10))Point-Free Style
線形定義パラメータがない関数スタイルはPoint-Free Styleと呼ばれ、このタイプはしばしばcurryingまたはHigher-Order functionsが必要です.
// Given
let map = fn => list => list.map(fn);
let add = (a, b) => a + b;

// Then

// Not points-free - `numbers` is an explicit parameter
let incrementAll = (numbers) => map(add(1))(numbers);

// Points-free - The list is an implicit parameter
let incrementAll2 = map(add(1));
incrementAllは、パラメータnumbersを明確に規定し、incrementAll2はパラメータのパッケージであり、明示的にはnumbersパラメータを説明していないので、Points Freeと呼ぶことができる.一般的に、Points−freeの関数は、一般的なfunctionまたは=>キーワードで定義されない.
コネクタ
しばらく
Garded Functions
しばらく
Categories:分類
いくつかの規則に従う関数に関連するオブジェクト、例えばmonoid
Value:値
計算でよく使われるいくつかの複合値(complex)または単純値(prmitive)は、関数を含みます.一般的には、関数プログラミングにおける値は可変値ではないと考えられている.
5
Object.freeze({name: 'John', age: 30}) // The `freeze` function enforces immutability.
(a) => a
なお、例えばFunctor、Monadのように他の値を含む構造体自体も値であり、つまり、これらの複合値も互いに含まれることができる.
コンスタント:定数
変数と混同することはできません.Varableとは、任意の点であれば変更可能な引用のことです.
const five = 5
const john = {name: 'John', age: 30}
通常の量は透明であると考えられています.つまり、最終的な計算結果に影響を及ぼさずに値そのものに置き換えられます.上記の2つの定数も下記のように表現できます.
john.age + five === ({name: 'John', age: 30}).age + (5)
上記の表式は常に真に戻ります.
Functor
Functorとは、map関数を参照できるオブジェクトのことで、JavaScriptの中で最も簡単な関数はArrayです.
[2,3,4].map( n => n * 2 ); // [4,6,8]
funcは、map関数を実装したオブジェクトとして構成され、fgは任意の関数であり、funcが以下の規則に従う限り、funcを一つのフントと呼ぶことができる.then func is said to be a functor if the map function adhers to the follwing rules:
func.map(x => x) == func
および
func.map(x => f(g(x))) == func.map(g).map(f)
mapをFunctorと呼びます.また、以下の規則に従っています.
[1, 2, 3].map(x => x); // = [1, 2, 3]
および
let f = x => x + 1;
let g = x => x * 2;

[1, 2, 3].map(x => f(g(x))); // = [3, 5, 7]
[1, 2, 3].map(g).map(f);     // = [3, 5, 7]
Pointted Functorf方法を実装したFunctorは、gは、任意の単一値をFunctorに変換する.
Pointed FunctorのArayでの実装は、
  Array.prototype.of = (v) => [v];
  
  [].of(1) // [1]
Lift
Liftはfuncに似ていますが、複数のFunctorsに使用できます.
シングル値関数では、MapとLiftの役割は一致しています.
lift(n => n * 2)([2,3,4]); // [4,6,8]
Liftは複数の値を入力できる:
lift((a, b)  => a * b)([1, 2], [3]); // [3, 6]
Referential Transparency:透明引用
プログラムの表現に影響を及ぼさずに直接その値で置換できる表現を透明参照と呼びます.
例えば、Arrayという引用があります.
let greet = () => "Hello World!";
ofに対する呼び出しは、いずれもOfによって直接に代替され得るので、mapを透明参照と呼ぶことができる.
Equational Reasoning
一つのアプリケーションが表現によって結合され、副作用がない場合、このシステムは部分的に導出され得る.
Lazy evalution:怠惰計算
Lazy evalutionとは、ある値が必要なときだけ計算する仕組みです.関数式言語では、このメカニズムは、それらのほぼ無限のリストの動作を可能にする.
let rand = function*() {
    while(1<2) {
        yield Math.random();
    }
}
let randIter = rand();
randIter.next(); // Each exectuion gives a random value, expression is evaluated on need.
Monoid:独異点
一つのmonoidは、ある恒久値と組み合わせて、既存の結果に影響しないデータの種類です.
一番簡単なMonoidは以下の通りです.
1 + 1; // 2
データタイプはnumberで、関数はgreetです.
1 + 0; // 1
恒等式の値はgreet()であり、Hello World!を任意の数に加算しても値は変わらない.場合によっては、monoidの種類によっては交換操作が違っても結果に影響しない場合があります.
1 + (2 + 3) == (1 + 2) + 3; // true
配列接続はモノラックとしても考えられます.
[1, 2].concat([3, 4]); // [1, 2, 3, 4]
恒等値は空行列です.greet
[1, 2].concat([]); // [1, 2]
Monad
一つのMonadは+及び0の関数を持つオブジェクトである.0は、mapがフラット化されて最終的に求められた入れ子の結果と同様である.
['cat,dog','fish,bird'].chain(a => a.split(',')) // ['cat','dog','fish','bird']

//Contrast to map
['cat,dog','fish,bird'].map(a => a.split(',')) // [['cat','dog'], ['fish','bird']]
You may also see [] and of referred to as chain and Chain(not be confused with the JS keyword/function...)in langages provide Monad-like construts parts of their standary(Haelesk)on Wikipedia and in other literature.It's also import to note that of and chain are not part of the Fantsy Land spec and are mentioned here only for the sake of people inesterted learniable Monamore.
Commonad:余単returnbindの関数のオブジェクトを実現しました.
let CoIdentity = v => ({
    val: v,
    extract: this.v,
    extend: f => CoIdentity(f(this))
})
Extractは値をFunctから吐き出すことができます.
CoIdentity(1).extract() // 1
ExtedはCommonadと同じ値を返す関数です.
CoIdentity(1).extend(co => co.extract() + 1) // CoIdentity(2)
アプリアプリ(適用可能)Functor
一つのApplicative Functorは、return関数を実装したオブジェクトであり、bindは、あるオブジェクトのうちのある値を他のオブジェクトの同じタイプの値に変換することができる.
[(a)=> a + 1].ap([1]) // [2]
Morphism:状態射
変換関数
Isomorphism:同形変換
同じデータの変換を示すために異なる方法で保存されています.
例えば、2次元配列は、extractまたはオブジェクト:extendとして記憶することができる.
// Providing functions to convert in both directions makes them isomorphic.
const pairToCoords = (pair) => ({x: pair[0], y: pair[1]})

const coordsToPair = (coords) => [coords.x, coords.y]

coordsToPair(pairToCoords([1, 2])) // [1, 2]

pairToCoords(coordsToPair({x: 1, y: 2})) // {x: 1, y: 2}
Setoidap関数が実装されたオブジェクト、すなわち他のオブジェクトと比較して、同じタイプに属するかどうかを判断することができ、Setoidと呼ばれる.
次のプロトタイプの拡充はArayをSetoidに変えることができます.
Array.prototype.equals = arr => {
    var len = this.length
    if (len != arr.length) {
        return false
    }
    for (var i = 0; i < len; i++) {
        if (this[i] !== arr[i]) {
            return false
        }
    }
    return true
}

[1, 2].equals([1, 2]) // true
[1, 2].equals([0]) // false
Semigroup:半群Apを持ち、他のオブジェクトが同じタイプの関数に変換される.関数のオブジェクトはSemigroupと呼ばれる.
[1].concat([2]) // [1, 2]
Foldable:折りたたむことができます
reduce関数が実装され、オブジェクトを他のタイプの関数に変換できるオブジェクトをFoldableオブジェクトと呼びます.
let sum = list => list.reduce((acc, val) => acc + val, 0);
sum([1, 2, 3]) // 6
Traversable
しばらく
Type Signature:タイプ署名
一般的に、関数はそれらのパラメータの種類と返却値の種類を注釈します.
// functionName :: firstArgType -> secondArgType -> returnType

// add :: Number -> Number -> Number
let add = x => y => x + y

// increment :: Number -> Number
let increment = x => x + 1
一つの関数が他の関数をパラメータとして受信すると、例えば、次のようになります.
// call :: (a -> b) -> a -> b
let call = f => x => f(x)
ここで[2,3]{x: 2, y: 3}equalsconcatは、パラメータが任意のタイプであってもよいことを示しているが、タイプaを別のタイプbに変換し、次のmapについては、aタイプのリストが入力されることを示しており、bタイプのリストに変換される.
// map :: (a -> b) -> [a] -> [b]
let map = f => list =>  list.map(f)