K-combinatorは以下のように実装することができ、実装に副作用があってはいけません。javascriptでのK-combinator(Kestrel)の実際の使用
const K = x => y => x;
「const」(Haskellのように)と呼ばれることがあります。 K関数は、「値をとり、常にその値を返す(定数)単項関数を返します」と定義されている可能性があります。
いつ便利ですか?実践的な事例を教えてください。
K-combinatorは以下のように実装することができ、実装に副作用があってはいけません。javascriptでのK-combinator(Kestrel)の実際の使用
const K = x => y => x;
「const」(Haskellのように)と呼ばれることがあります。 K関数は、「値をとり、常にその値を返す(定数)単項関数を返します」と定義されている可能性があります。
いつ便利ですか?実践的な事例を教えてください。
K
の問題は、すべてのプリミティブコンビネータと同様に、単独では考慮できないことです。プリミティブコンビネータは、関数型プログラミングの基本ブロックです。あなたは仕事でそれらを見るために適切なコンテキストが必要です。あなたが機能的なパラダイムに慣れていないなら、この文脈を突き詰めることが課題です。
ここには「典型的な文脈」があります:Option
です。 Option
タイプのインスタンスがnull
かもしれ値のようなものですが、機能に適用された場合、エラーをスローすることはありません:
// the option type
const Option = {
some: Symbol.for("ftor/Option.some"),
none: Symbol.for("ftor/Option.none"),
of: x => factory(Option.some) (x),
cata: pattern => o => pattern[o.tag](o.x),
fold: f => g => o => Option.cata({[Option.some]: f, [Option.none]: g}) (o),
map: f => o => Option.fold(x => Option.of(f(x))) (K(o)) (o)
// ^^^^
}
// a generic map function
const map = type => f => o => type.map(f) (o);
// functor factory
const factory = tag => value => (
{x: value === undefined ? null : value, tag: tag}
);
// auxiliary functions
const K = x => y => x;
const sqr = x => x * x;
// a few data to play around
const o = factory(Option.some) (5);
const p = factory(Option.none)();
// and run
let r1 = map(Option) (sqr) (o);
let r2 = map(Option) (sqr) (p);
console.log("map over o", r1);
console.log("map over p", r2);
K
は、この実装では何をしますか?のは、決定的なラインを見てみましょう:
f => o => Option.fold(x => Option.of(f(x))) (K(o)) (o)
Option.fold
は2つの機能を期待しています。最初に渡された関数x => Option.of(f(x))
は、some
の場合です(値があります)。 2番目はnone
の場合のK(o)
です(値はありません)。 K
は2つの引数K = x => y => {return x}
を期待していることを思い出してみましょう。 K(o)
はo
をx
に割り当てます。第2引数として渡された内容に関係なく、K
は常にy
を無視し、代わりにx
を返します。
o
は式K(o)
の中で何を表していますか?それはOption.none
を表します。つまり、値が存在しません。したがって、f
をnone
にマップしようとすると、f
がK
に渡されても、none
が返されます。
前提条件関数 "precon"はどこにありますか? –
教会でコード化されたブーリアンを使用する場合、Kコンビネータを真理値として使用することもできます。 I. IF-TEST THEN ELSE: "IF-TEST"がKを返した場合、 "else"が削除され、 "then"が実行されます。
すべてのコードスニペット? –
よくある質問ですが、好きです。私はそれが好きです。
私の例をサポートするために、この回答では&hellipを実装します。
abuild :: Number -> (Number -> a) -> [a]
…型が示唆するように、配列を構築するための数と関数を取ります。これは、ある計算に基づいて既知のサイズの配列を作成する場合に便利です。
アイデンティティ関数id
を使用して5つの要素で配列を作成しましょう。あなたが見ることができるように、0から始まる連続的な数値指標は、あなたのビルダー機能
abuild(5)(ID) // => [0,1,2,3,4]
に与えられ、今回は建築家と数学をしましょう。入力を正方形にします。非常に高度な。
abuild (5) (x=> x * x)
// => [0,1,4,9,16]
おそらく入力については気にしません。私はいつも良い笑いが大好きです。私は物事を絶えず笑う。 1つは私が言うことができるK('ha')
…
abuild (5) (K('ha'))
// => ['ha','ha','ha','ha','ha']
ブーム!かなり便利ですよね?それは
は先に行くと行動でK
を見るためにそれを実行K
実装です!
// id :: a -> a
const id = x=> x
// K :: a -> b -> a
const K = x=> y=> x
// add :: Number -> Number -> Number
const add = x=> y=> y + x
// reduce :: (a -> b) -> b -> [a] -> b
const reduce = f=> y=> ([x,...xs])=> {
if (x === undefined)
return y
else
return reduce (f) (f (y) (x)) (xs)
}
// map :: (a -> b) -> [a] -> [b]
const map = f=> reduce (xs=> x=> [...xs, f(x)]) ([])
// iterate :: Number -> (a -> a) -> a -> [a]
const iterate = n=> f=> x=>
n > 0 ? [x, ...iterate (n - 1) (f) (f(x))] : []
// abuild :: Number -> (Number -> a) -> [a]
const abuild = n=> f=>
map (f) (iterate (n) (add (1)) (0))
console.log(abuild (5) (id))
// => [0,1,2,3,4]
console.log(abuild (5) (x=> x * x))
// => [0,1,4,9,16]
console.log(abuild (5) (K('ha')))
// => ['ha','ha','ha','ha','ha']
http://cs.stackexchange.com/questions/55441/what-is-the-purpose-of-the-ski-combinator-calculusor-even-lambda-calculus- wha –
非常に便利なCL関数[constanty](http://clhs.lisp.se/Body/f_cons_1.htm)のようです。 – Sylwester
カレー言語では、最初の引数をコールバックで無視する場合に使用します。 – Bergi