コンテナタイプ([]
/{}
)を使用せずにJavascriptでファンクタを実装しようとしています。したがって、私は単にそれらを構築するために、純粋な高次の機能を利用:ファンクタまたはモナドはそれぞれ高次関数で表現できますか?
const option = x => f => isAssigned(x) ? option(f(x)) : none;
const none = option(null);
const isAssigned = x => x !== null && x !== undefined;
const inc = x => x + 1;
const sqr = x => x * x;
const head = xs => xs[0]
const log = x => (console.log(x), x);
option(head([4])) (inc) (sqr) (log); // 25
option(head([])) (inc) (sqr) (log); // not executed
option
は、値と純粋な関数を受け取り、そのコンテキストに機能を持ち上げ、値に適用し、返します結果は同じ文脈になる。私はそれがファンクタだと思います。しかし、Javascriptのfunctor prototcolには従っておらず、各functorはそのプロトタイプ上にmap関数を所有していなければなりません。 option
は実際に私の質問がある関手提供
const option = x => f => isAssigned(x) ? option(f(x)) : none;
const option_ = x => f => isAssigned(x) ? flatten(option(f(x))) : none;
const none = option(null);
const of = x => option(x); // return
const flatten = F => { // it gets a bit ugly here
let y;
F(z => (y = z, z));
return y;
};
// auxiliary functions
const compn = (...fs) => x => fs.reduceRight((acc, f) => f(acc), x);
const getOrElse = x => F => {
let y;
F(z => (y = z, z));
return isAssigned(y) ? y : x;
};
const isAssigned = x => x !== null && x !== undefined;
const log = prefix => x => (console.log(prefix, x), x);
const head = xs => xs[0];
const head_ = xs => option(xs[0]);
const sqr = x => x * x;
// some data
const xs = [5],
ys = [];
// run
const w = option(xs) (head),
x = option(ys) (head),
y = option_(xs) (head_),
z = option_(ys) (head_);
log("square head of xs:") (compn(sqr, getOrElse(1)) (w)); // 25
log("square head of ys:") (compn(sqr, getOrElse(0)) (x)); // 0
log("square head_ of xs:") (compn(sqr, getOrElse(0)) (y)); // 25
log("square head_ of ys:") (compn(sqr, getOrElse(0)) (z)); // 0
:
option
は明らかにモナドのようなタイプ(少なくとも、それは私の例では1のように振舞う)に拡張することができます。コールスタックにコンテキスト(または効果)計算の結果が保持されている(純粋な)高次関数を持つすべてのファンクタ/モナドを単独で表現することは可能ですか?
は、なぜあなたはこれをしたいですか?他の解決方法がありますか? – niceman
@ftor [Church encoding](https://en.wikipedia.org/wiki/Church_encoding)のようなものを意味しますか? – phg
@phg理論的根拠、ありがとう。理論的には可能です。私はまだJavascriptでそれらを実装する実用的な問題があるかどうか疑問に思います。これまで 'option'には(proto)型はありません。関数( 'of'のような)を右のモナドに関連付けるにはどうすればいいですか?さらに、 'option'は共用体にすぎません。タグがなく、組合が採用した可能性のあるタイプを反映する手段がない。 – ftor