chain
方法なぜファンタジーランド仕様でチェーンが同じチェーンの値を返す必要があるのですか?
chain
方法を提供しなければならない鎖を有する値。チェーン 方法は、一つの引数を取る:
m.chain(f)
f
はf
が機能しない場合、chain
の動作が指定されていない値を
- を返す関数でなければなりません。
f
は同じチェーンchain
の値を返す必要がありますオプションモナドの単純な実装で考えると、同じチェーン
の値を返す必要があります。
// prototypes:
const someProto = {
of(x) { return some(x) },
map(f) { return some(f(this.x)) },
ap(ftor) { return ftor.map(this.x) },
join() { return this.x },
chain(mf) { return this.map(mf).join() }
};
const noneProto = {
of() { return this },
map() { return this },
ap() { return this },
join() { return this },
chain() { return this }
};
// factories:
function some(x) {
return Object.assign(Object.create(someProto), {x: x});
}
function none() {
return Object.assign(Object.create(noneProto), {x: null});
}
chain
が常にオプションのモナドを返すことを保証するには、mf
(モナド関数)が常に1を返すようにする必要があります。 mf
は実装の一部ではないため、これは不可能です。モナドを使用する場合、むしろ定義されています:
// auxiliary function:
const sub = y => x => x - y;
let a = some(2);
let b = some(3);
a.chain(x => b.chain(y => some(sub(x)(y)))); // {x: 1}
a.chain(x => b.chain(y => sub(x)(y))); // 1 - ouch!
第2の方法アプリケーションに渡された関数は、モナド計算の開封された結果をもたらすないモナドを返しません。私はタイプチェックをchain
またはjoin
に追加することができます。ダックタイピングによって、問題を解決することができます。これはかなり醜いでしょう。
仕様では、この時点で型の安全性が必要なのはなぜですか? Javascriptは動的に型付けされており、実行時に型チェックを実行する代わりに適切な単体テストを記述することをお勧めします。私は仕様に違反しますか? 2番目の例では
問題は、私が2番目の例で行ったやり方でこのオプションの実装を誤用して、仕様に違反した場合です。したがって、私の実装はファンタジーランドに準拠していない可能性があります。これを防ぐ唯一の方法は、実行時に型チェックを追加することです。私はこれが一種の醜いと信じています。 – ftor
オプションのモナドの実装は、仕様と互換性があります。あなたの 'の使用。chain() 'はそうではありません。あなたのChainableのユーザは、彼らが提供している機能に応じて '.chain()'または '.map()'のいずれかの適切なメソッドを使うことが期待されます。 – ErikR
OK、私は完全に確信していませんが、答えを受け入れる、ありがとう! – ftor