SlideShare uma empresa Scribd logo
1 de 83
Baixar para ler offline
JavaScriptで学ぶ
関数型プログラミング
第4章"高階関数
小式澤!篤!(@lastarrow21)
Topotal'輪読会
2015%02%11
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 1
出典
• JavaScriptで学ぶ関数型プログラミング
• Michael/Fogus/著
• 和田/祐一郎/訳
• O'REILLY/®/オライリー・ジャパン/出版
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 2
前置き
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 3
前置き
• 自由変数をわかりやすくするために、変数名を全て大文字表記
にしている
• 一般的なプログラミングスタイルでは推奨されない
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 4
(復習)
クロージャ
3.5.1%節
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 5
クロージャ
• プログラム内で環境を共有する仕組み
• スコープの実行完了後でも内部情報を保持し続ける関数
function makeAdder(CAPTURED) { // CAPTURED : 自由変数 (確保される変数)
return function(free) { return free + CAPTURED };
}
var add10 = makeAdder(10); // add10 が"10"を確保
add10(32); // => 42
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 6
4章"高階関数
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 7
高階関数
• 前提
• 第一級のデータ型である
• 次のうち、少なくともどちらか一方を満たす
• 引数として関数をとる
• 関数を戻り値として返す
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 8
高階関数
• 前提
• 第一級のデータ型である
• 次のうち、少なくともどちらか一方を満たす
• 引数として関数をとる"!"まずはここから考える
• 関数を戻り値として返す
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 9
4.1$引数として関数を取る関数
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 10
引数として関数を取る関数
• 既に(4章よりも前に)登場している
• _.map、_.reduce、_.filter
• 関数を引数に取ることに関して、もう少し詳しく考える
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 11
4.1.1$関数を渡すことを考える
max、finder、best
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 12
「関数を渡す」と何ができるのか
• 配列などから最大値を返す関数"_.max
console.log(_.max([1, 2, 3, 4, 5]));
// => 5
• 第二引数に、関数を渡すことができる"!"高階関数
var people = [{ name : "Fred", age : 65 },
{ name : "Lucy", age : 36 }];
console.log(_.max(people, function(p){ return p.age }));
// => {name : "Fred", age : 65}
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 13
_.maxの考察
• 関数を引数に取れる
• 任意のオブジェクト同士を比較する手段を提供している
• 関数を構築する上で有用
• 常に">"(大なり)を用いて比較している
• この制限により、本当に関数型であるとはいえない
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 14
「良い」値を返す関数finder
• 第1,$第2引数は関数
• 比較するデータから比較できるように値を作る関数
• 2つの値を比較して、そこから「良い」値を返す関数
• 第3引数は比較するデータを含むオブジェクトの配列
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 15
「良い」値を返す関数finderの実装
function finder(valueFun, bestFun, coll) {
return _.reduce(coll, function(best, current) {
var bestValue = valueFun(best);
var currentValue = valueFun(current);
return (bestValue === bestFun(bestValue, currentValue))
? best : current;
});
}
finder(_.identity, Math.max, [1, 2, 3, 4, 5]); // => 5
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 16
「良い」値を返す関数finderの他の用例
• プロパティ名ageを比較して最大のものを「良い」とする
finder(plucker('age'), Math.max, people);
// => { name : "Fred", age : 65 }
• プロパティ名nameの最初の文字がLであるものを「良い」とす
る
finder(plucker('name'),
function(x, y){ return (x.charAt(0) === "L") ? x : y },
people);
// => { name : "Lucy", age : 36 }
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 17
「良い」値を返す関数finderの考察
• 比較の仕方を関数で指定できる
• 様々なタイプの「最良の値を探す」関数を生成できる
• ロジックを複製している箇所がある
// finder関数内
return (bestValue === bestFun(bestValue, currentValue))
? best : current;
// 「最良の値を探す」bestFun関数内
return (x.charAt(0) === "L") ? x : y;
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 18
ロジックの複製を回避するために
• 最良の値を判定する関数は
• 最初の引数が2つ目の引数よりも良い場合にtrueを返す
• 渡された引数を比較できる形まで紐解く方法を知っている
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 19
よりエレガントな関数bestの実装
function best(fun, coll){
return _.reduce(coll, function(x, y){
return fun(x, y) ? x : y;
});
}
console.log(best(function(x, y){ return x > y; },
[1, 2, 3, 4, 5]));
// => 5
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 20
より良い値を探す関数の考察
• 2つの関数を引数に取る関数#finder
• ロジックの重複が発生した
• ロジックの重複を削除することに一般化した関数#best
• 引き締まった
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 21
より一般的な関数に作り直すには
4.1.2%関数を渡すことを更に考える
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 22
指定した回数だけ値を格納する関数!repeat
function repeat(times, VALUE) {
return _.map(_.range(times),
function() { return VALUE; });
}
repeat(4, "Major");
// => ["Major", "Major", "Major", "Major"]
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 23
関数!repeat!の考察
• とても素直な実装
• 「一般的な繰り返し」とは言えない
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 24
関数!repeat!の考察
• とても素直な実装
• 「一般的な繰り返し」とは言えない
• 計算を繰り返したいことがある
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 25
関数!repeat!の考察
• とても素直な実装
• 「一般的な繰り返し」とは言えない
• 計算を繰り返したいことがある
「値ではなく関数を使え」
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 26
繰り返し計算した結果を格納する関数!repeatedly
function repeatedly(times, fun) {
return _.map(_.range(times, fun);
}
repeatedly(3, function() {
return Math.floor(Math.random() * 10 + 1);
});
// => [1, 3, 8]
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 27
関数!repeatedly!の考察
• 関数を呼ぶことによって任意の値が格納されるようになった
• もちろん固定値も格納できる
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 28
関数!repeatedly!の考察
• 関数を呼ぶことによって任意の値が格納されるようになった
• もちろん固定値も格納できる
repeatedly(3, function() { return "Odeley!"; });
// => { "Odeley!", "Odeley!", "Odeley!" }
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 29
関数!repeatedly!の考察
• 関数を呼ぶことによって任意の値が格納されるようになった
• もちろん固定値も格納できる
repeatedly(3, function() { return "Odeley!"; });
// => { "Odeley!", "Odeley!", "Odeley!" }
• 引数に関係なく固定値を返す関数はよくある話
(詳しくは5章にて)
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 30
「値ではなく関数を使え」(再掲)
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 31
「値ではなく関数を使え」
• 関数"repeatedly"で、格納される値が関数によって任意に生成
されるようになった
• ただし、反復回数がいつもわかるとは限らない
// for文による例
for (let i = 2; i <= 1024; i = i * 2) {
console.log(i);
} // => 2 4 8 16 32 64 128 256 512 1024
// 10回繰り返された
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 32
さらに進化した関数!iterateUntil
• 第一引数"fun
• 格納する値を生成する関数
• 第二引数"check
• 繰り返しが終了すべき時にfalseを返す関数
• 第三引数"init
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 33
さらに進化した関数!iterateUntil
function iterateUntil(fun, check, init) {
var ret = [];
var result = fun(init);
while (check(result)) {
ret.push(result);
result = fun(result);
}
return ret;
}
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 34
iterateUntil!の使用例
iterateUntil(function(n) { return n * 2; },
function(n) { return n <= 1024; },
1);
// => [ 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024 ]
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 35
関数!iterateUntil!の考察
• 繰り返し条件が関数"check"の結果依存になった
• 実質無制限
• 終了条件だけ知っている場合も用いれる
!!関数!repeatedly!の1段階上の存在となった
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 36
高階関数
• 前提
• 第一級のデータ型である
• 次のうち、少なくともどちらか一方を満たす
• 引数として関数をとる
• 関数を戻り値として返す"!"次はこっち
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 37
4.2$他の関数を返す関数
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 38
今までの関数を返す関数
• makeAdder
• 自由変数と引数の和を返す関数を返す
• complement
• 引数にとった関数の真偽値判定が逆になる関数を返す
• plucker
• 引数にとった値をキーとして対応する値を返す関数を返す
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 39
定数を返す関数!always
• 関数"repeatedly"では引数を無視して値を返す関数を使った
• 定数を返す関数":"k"と呼ばれる
• ここでは"always"と呼ぶ
function always(VALUE) {
return function() { return VALUE; };
}
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 40
クロージャ使用上の注意!(1/2)
• 関数は常に唯一の値を生成する
• 自由変数VALUEに束縛された戻り値は常に等しい'[Braithwaite,'
'13]
var f = always(function(){});
f() === f(); // => true
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 41
クロージャ使用上の注意!(2/2)
• 新しく生成されたクロージャは、それぞれ異なる値を返す
var f = always(function(){});
var g = always(function(){});
f() === g(); // => false
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 42
関数!always!の使用例
• 無名関数の代わりに使うとコードがすっきりする
repeatedly(3, always("Odelay!"));
//=> [ "Odelay!", "Odelay!", "Odelay!" ]
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 43
関数!invoker
• 第一引数"NAME
• 第二引数のMETHODを実行する対象
• 第二引数"METHOD
• 実行するメソッド名
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 44
関数!invoker!の実装
function invoker (NAME, METHOD) {
return function(target /* args ... */) {
if (!existy(target)) fail("Must provide a target");
var targetMethod = target[NAME];
var args = _.rest(arguments);
return doWhen((existy(targetMethod) && METHOD === targetMethod),
function() {
return targetMethod.apply(target, args);
});
};
}
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 45
関数!invoker!の使用例
var rev = invoker('reverse', Array.prototype.reverse);
_.map([[1,2,3]], rev);
//=> [ [ 3,2,1 ] ]
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 46
関数!invoker!の考察
• invoker"が返す関数はクロージャ
• reverse"などを保持しておいて、後で使用する"(revの設定
データ)
• 関数"always"とは違って、特別な処理を行う関数を返す
• 関数型プログラミングでは、オブジェクトを引数に取ることを
好む
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 47
4.2.1%引数を高階関数に確保する
• Ques&on.*なぜ関数を返す関数を生成するの?
• Hint.*高階関数に渡す引数は、返される関数の設定項目
var add100 = makeAdder(100);
add100(38); // => 138
• makeAdder関数に100という値を設定したものをadd100とい
う名前に束縛した
• ここからは、変数を確保した関数を返す関数の話
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 48
4.2.2$大義のために変数を確保する
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 49
例!:!ユニークに文字列を生成する関数
素朴な実装の場合
function uniqueString(len) {
return Math.random().toString(36).substr(2, len);
};
uniqueString(10);
//=> liydklvjbk
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 50
ランダム文字列に接頭辞を付けたくなったら?
関数!uniqueString!を修正する
function uniqueString(prefix) {
return [prefix, new Date().getTime()].join('');
};
uniqueString("argento");
//=> "argento1356107740868"
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 51
また要件が変わった!
• 要件":"指定した文字列に連番をつけたもの
function makeUniqueStringFunction(start) {
var COUNTER = start; // suffixの開始番号
return function(prefix) {
return [prefix, COUNTER++].join('');
}
};
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 52
関数!makeUniqueStringFunction!の実行例
// 連番は0からスタート
var uniqueString = makeUniqueStringFunction(0);
uniqueString("dari");
//=> "dari0"
uniqueString("dari");
//=> "dari1"
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 53
オブジェクトによる!makeUniqueStringFunction!の
再実装
var generator = {
count: 0,
uniqueString: function(prefix) {
return [prefix, this.count++].join('');
}
};
generator.uniqueString("bohr"); // => bohr0
generator.uniqueString("bohr"); // => bohr1
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 54
オブジェクト!generator!の危険性
• count"プロパティに再代入すると"!
generator.counter = "gotcha";
console.log(generator.uniqueString("bohr"));
// --> bohrNaN
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 55
オブジェクト!generator!の改良
var omgenerator = ( function(init) {
var COUNTER = init;
return {
uniqueString: function(prefix) {
return [prefix, COUNTER++].join('');
}
}
})(0);
print(omgenerator.uniqueString("lichking-"));
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 56
オブジェクト!omgenerator!の考察
• COUNTER"の隠 には成功した
• 非常に美しくない
• ECMAScript.next"では頑張っている
• makeUniqueStringFunction"のようにクロージャを使えば
美しい
• 参照透明性がない
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 57
参照透明性
• 関数が返す結果がその引数によってのみ左右されること
• makeUniqueStringFunction"が返す値は自身の実行回数依
存
• 何回呼び出したかは知ることは不可能
• 詳しくは7章で
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 58
「存在しない状態」
var nums = [1,2,3,null,5];
_.reduce(nums, function(total, n) { return total * n });
//=> 0
doSomething({ WhoCares: 42, critical: null });
//!!"
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 59
「存在しない状態」に備える関数!fnull
• 「存在しない状態」に対する防御のための関数
• fnull"の引数は関数と1つ以上のデフォルト値
• fnull"が返す関数の引数に"null"や"undefined"が混ざってい
たら、デフォルト値がかわりに用いられる
• デフォルト値の代入は、必要なときが来るまで遅延される
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 60
関数!fnull!の実装
function fnull(fun /*, default value */) {
var defaults = _.rest(arguments);
return function(/* args */) {
var args = _.map(arguments, function(e, i) {
return existy(e) ? e : defaults[i];
});
return fun.apply(null, args);
};
}
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 61
関数!fnull!の使用例(1)!:!数値 null
var nums = [1,2,3,null,5];
var safeMult = fnull(
function(total, n) { return total * n },
1, 1
);
_.reduce(nums, safeMult);
//=> 30
• nullはデフォルト値"1"に置換される
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 62
関数!fnull!の使用例(2)!:!設定オブジェクト
function defaults(d) {
return function(o, k) {
var val = fnull(_.identity, d[k]);
return o && val(o[k]);
};
}
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 63
関数!defaults!の利用
function doSomething(config) {
var lookup = defaults({critical: 108});
return lookup(config, 'critical');
}
doSomething({critical: 9});
//=> 9
doSomething({});
//=> 108
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 64
関数!fnull!の考察
• 危険な値(undefinedやnullなど)を気の利いたデフォルト値に
変更できる
• o[k] || someDefault$とか書かなくても良くなる
• doSomething$関数と離れた場所で引数のチェックを行える
• 引数の検証ロジックをカプセル化できた
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 65
4.3$すべてを結集
オブジェクトバリデータ
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 66
4.3$すべてを結集オブジェクトバリデータ
• 任意の基準に基いて妥当性を検証する
• 流暢なものがいい
• パーツから構成したい
• 発生したエラーを全て報告して欲しい
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 67
関数!checker
• 真偽値を返す関数を引数にとる
• false"が返ってきたら、エラーメッセージを追加する
• 真偽値を返す関数の"message"フィールドを探す
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 68
関数!checker!の実装
function checker(/* validators */) {
var validators = _.toArray(arguments);
return function(obj) {
return _.reduce(validators, function(errs, check) {
if (check(obj))
return errs;
else
return _.chain(errs).push(check.message).value();
}, []);
};
}
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 69
関数!checker!の使用例
• エラーメッセージが擬似メタデータとして付与された特殊用途
の検証用関数
• 一般的な解決方法ではないが、使える
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 70
関数!checker!の使用例
var alwaysPasses = checker(always(true), always(true));
alwaysPasses({}); // => []
var fails = always(false);
fails.message = "人生における過ち";
var alwaysFails = checker(fails);
alwaysFails({}); // => [ "人生における過ち" ]
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 71
message!プロパティを与えることの問題
• 検証用関数を生成する度に"message"を与えるのは面倒
• もとからある"message"プロパティを削除する可能性がある
• _message"としても良いが、今度は"_message"思い出さなけ
ればならない
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 72
関数!validator
• message"プロパティを与えることの問題を解決する高階関数
function validator(message, fun) {
var f = function(/* args */) {
return fun.apply(fun, arguments);
};
f['message'] = message;
return f;
}
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 73
関数!validator!の使用例
var gonnaFail =
checker(validator("ZOMG!", always(false)));
console.log(gonnaFail(100));
// => [ "ZOMG!" ]
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 74
検証用関数を分離して定義する利点
• 検証用関数にわかりやすい名前を付与できる
function aMap(obj) {
reutrn _.isObject(obj);
}
var checkCommand =
checker(validator("マップデータである必要があります", aMap));
checkCommand({}); // => []
checkCommand(42); // => [ "マップデータである必要があります" ]
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 75
流暢な検証関数
• 関数を返す関数に渡す引数は、返される関数の動作を「設定」
するもの
• 例:#必要なキーの単純なリストは美しく流暢
• hasKeys('msg', 'type')とか
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 76
関数!hasKeys!の実装
function hasKeys(/* 検証したいキーのリスト */) {
var KEYS = _.toArray(arguments);
var fun = function(obj) {
return _.every(KEYS, function(k) {
return _.has(obj, k);
});
};
fun.message =
cat(["Must have values for keys:"], KEYS).join(" ");
return fun;
}
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 77
関数!hasKeys!の特徴
• 自由変数"KEYS"を確保したクロージャが妥当性検証を行う
• hasKeys"関数は"fun"関数実行時の設定を行う
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 78
関数!hasKeys!の使用例
var checkCommand =
checker(validator("must be a map", aMap),
hasKeys('msg', 'type'));
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 79
checkCommand!の使用例
checkCommand({msg:0"blah",0type:0"display"});
//0=>0[0]
checkCommand(32);
//0=>0[0"マップデータである必要があります",0"Must0have0values0for0
keys:0msg0type"0]
checkCommand({});
//0=>0[0"Must0have0values0for0keys:0msg0type"0]
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 80
4.4#まとめ
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 81
高階関数の特徴!(再掲)
• 前提
• 第一級のデータ型である
• 次のうち、少なくともどちらか一方を満たす
• 引数として関数をとる
• 関数を戻り値として返す
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 82
4章"高階関数"まとめ
• 関数を他の関数に渡した
• iterateUntil"などを例に、関数に関数を渡したほうが良
い場合を示した
• 関数が関数を返す関数を定義した
• 予期しない値に対する防御策"fnull
• 強力な制約関数"checker,"validator,"hasKeys
KOSHIKIZAWA)Atsushi)(2015402411))第二回Topotal輪読会 83

Mais conteúdo relacionado

Mais procurados

関数型プログラミング入門 with OCaml
関数型プログラミング入門 with OCaml関数型プログラミング入門 with OCaml
関数型プログラミング入門 with OCamlHaruka Oikawa
 
Real World OCamlを読んでLispと協調してみた
Real World OCamlを読んでLispと協調してみたReal World OCamlを読んでLispと協調してみた
Real World OCamlを読んでLispと協調してみたblackenedgold
 
これから Haskell を書くにあたって
これから Haskell を書くにあたってこれから Haskell を書くにあたって
これから Haskell を書くにあたってTsuyoshi Matsudate
 
研究会20140618:進捗と闇Pythonistaのワンライナーテクニックを少々
研究会20140618:進捗と闇Pythonistaのワンライナーテクニックを少々研究会20140618:進捗と闇Pythonistaのワンライナーテクニックを少々
研究会20140618:進捗と闇Pythonistaのワンライナーテクニックを少々Peinan ZHANG
 
Java x Groovy: improve your java development life
Java x Groovy: improve your java development lifeJava x Groovy: improve your java development life
Java x Groovy: improve your java development lifeUehara Junji
 
Freer Monads, More Extensible Effects
Freer Monads, More Extensible EffectsFreer Monads, More Extensible Effects
Freer Monads, More Extensible EffectsHiromi Ishii
 
Lisp tutorial for Pythonista : Day 2
Lisp tutorial for Pythonista : Day 2Lisp tutorial for Pythonista : Day 2
Lisp tutorial for Pythonista : Day 2Ransui Iso
 
あなたのScalaを爆速にする7つの方法(日本語版)
あなたのScalaを爆速にする7つの方法(日本語版)あなたのScalaを爆速にする7つの方法(日本語版)
あなたのScalaを爆速にする7つの方法(日本語版)x1 ichi
 
LLdeade Python Language Update
LLdeade Python Language UpdateLLdeade Python Language Update
LLdeade Python Language UpdateAtsushi Shibata
 
Java SE 8 lambdaで変わる プログラミングスタイル
Java SE 8 lambdaで変わる プログラミングスタイルJava SE 8 lambdaで変わる プログラミングスタイル
Java SE 8 lambdaで変わる プログラミングスタイルなおき きしだ
 
(define)なしで再帰関数を定義する
(define)なしで再帰関数を定義する(define)なしで再帰関数を定義する
(define)なしで再帰関数を定義するblackenedgold
 
Scalaで萌える関数型プログラミング[1.1.RC1]
Scalaで萌える関数型プログラミング[1.1.RC1]Scalaで萌える関数型プログラミング[1.1.RC1]
Scalaで萌える関数型プログラミング[1.1.RC1]Ra Zon
 
命令プログラミングから関数プログラミングへ
命令プログラミングから関数プログラミングへ命令プログラミングから関数プログラミングへ
命令プログラミングから関数プログラミングへNaoki Kitora
 
関数型プログラミング in javascript
関数型プログラミング in javascript関数型プログラミング in javascript
関数型プログラミング in javascriptRyuma Tsukano
 
Scalaで型クラス入門
Scalaで型クラス入門Scalaで型クラス入門
Scalaで型クラス入門Makoto Fukuhara
 
The Why and How of Java8 at LINE Fukuoka
The Why and How of Java8 at LINE FukuokaThe Why and How of Java8 at LINE Fukuoka
The Why and How of Java8 at LINE FukuokaYouhei Nitta
 
Haskell勉強会 in ie
Haskell勉強会 in ieHaskell勉強会 in ie
Haskell勉強会 in iemaeken2010
 
サーバーサイドでの非同期処理で色々やったよ
サーバーサイドでの非同期処理で色々やったよサーバーサイドでの非同期処理で色々やったよ
サーバーサイドでの非同期処理で色々やったよkoji lin
 
BOF1-Scala02.pdf
BOF1-Scala02.pdfBOF1-Scala02.pdf
BOF1-Scala02.pdfHiroshi Ono
 

Mais procurados (20)

関数型プログラミング入門 with OCaml
関数型プログラミング入門 with OCaml関数型プログラミング入門 with OCaml
関数型プログラミング入門 with OCaml
 
Real World OCamlを読んでLispと協調してみた
Real World OCamlを読んでLispと協調してみたReal World OCamlを読んでLispと協調してみた
Real World OCamlを読んでLispと協調してみた
 
これから Haskell を書くにあたって
これから Haskell を書くにあたってこれから Haskell を書くにあたって
これから Haskell を書くにあたって
 
研究会20140618:進捗と闇Pythonistaのワンライナーテクニックを少々
研究会20140618:進捗と闇Pythonistaのワンライナーテクニックを少々研究会20140618:進捗と闇Pythonistaのワンライナーテクニックを少々
研究会20140618:進捗と闇Pythonistaのワンライナーテクニックを少々
 
Java x Groovy: improve your java development life
Java x Groovy: improve your java development lifeJava x Groovy: improve your java development life
Java x Groovy: improve your java development life
 
Freer Monads, More Extensible Effects
Freer Monads, More Extensible EffectsFreer Monads, More Extensible Effects
Freer Monads, More Extensible Effects
 
Lisp tutorial for Pythonista : Day 2
Lisp tutorial for Pythonista : Day 2Lisp tutorial for Pythonista : Day 2
Lisp tutorial for Pythonista : Day 2
 
Thinking in Cats
Thinking in CatsThinking in Cats
Thinking in Cats
 
あなたのScalaを爆速にする7つの方法(日本語版)
あなたのScalaを爆速にする7つの方法(日本語版)あなたのScalaを爆速にする7つの方法(日本語版)
あなたのScalaを爆速にする7つの方法(日本語版)
 
LLdeade Python Language Update
LLdeade Python Language UpdateLLdeade Python Language Update
LLdeade Python Language Update
 
Java SE 8 lambdaで変わる プログラミングスタイル
Java SE 8 lambdaで変わる プログラミングスタイルJava SE 8 lambdaで変わる プログラミングスタイル
Java SE 8 lambdaで変わる プログラミングスタイル
 
(define)なしで再帰関数を定義する
(define)なしで再帰関数を定義する(define)なしで再帰関数を定義する
(define)なしで再帰関数を定義する
 
Scalaで萌える関数型プログラミング[1.1.RC1]
Scalaで萌える関数型プログラミング[1.1.RC1]Scalaで萌える関数型プログラミング[1.1.RC1]
Scalaで萌える関数型プログラミング[1.1.RC1]
 
命令プログラミングから関数プログラミングへ
命令プログラミングから関数プログラミングへ命令プログラミングから関数プログラミングへ
命令プログラミングから関数プログラミングへ
 
関数型プログラミング in javascript
関数型プログラミング in javascript関数型プログラミング in javascript
関数型プログラミング in javascript
 
Scalaで型クラス入門
Scalaで型クラス入門Scalaで型クラス入門
Scalaで型クラス入門
 
The Why and How of Java8 at LINE Fukuoka
The Why and How of Java8 at LINE FukuokaThe Why and How of Java8 at LINE Fukuoka
The Why and How of Java8 at LINE Fukuoka
 
Haskell勉強会 in ie
Haskell勉強会 in ieHaskell勉強会 in ie
Haskell勉強会 in ie
 
サーバーサイドでの非同期処理で色々やったよ
サーバーサイドでの非同期処理で色々やったよサーバーサイドでの非同期処理で色々やったよ
サーバーサイドでの非同期処理で色々やったよ
 
BOF1-Scala02.pdf
BOF1-Scala02.pdfBOF1-Scala02.pdf
BOF1-Scala02.pdf
 

Semelhante a 【Topotal輪読会】JavaScript で学ぶ関数型プログラミング 4 章

【Topotal輪読会】JavaScript で学ぶ関数型プログラミング 2 章
【Topotal輪読会】JavaScript で学ぶ関数型プログラミング 2 章【Topotal輪読会】JavaScript で学ぶ関数型プログラミング 2 章
【Topotal輪読会】JavaScript で学ぶ関数型プログラミング 2 章YOSHIKAWA Ryota
 
JavaScript 講習会 #1
JavaScript 講習会 #1JavaScript 講習会 #1
JavaScript 講習会 #1Susisu
 
FP習熟度レベルとFSharpxのIteratee
FP習熟度レベルとFSharpxのIterateeFP習熟度レベルとFSharpxのIteratee
FP習熟度レベルとFSharpxのIterateepocketberserker
 
Scalaで萌える関数型プログラミング[完全版]
Scalaで萌える関数型プログラミング[完全版]Scalaで萌える関数型プログラミング[完全版]
Scalaで萌える関数型プログラミング[完全版]Ra Zon
 
po-6. 繰り返し実行(ループ),ステップ実行
po-6. 繰り返し実行(ループ),ステップ実行po-6. 繰り返し実行(ループ),ステップ実行
po-6. 繰り返し実行(ループ),ステップ実行kunihikokaneko1
 
Introduction of "the alternate features search" using R
Introduction of  "the alternate features search" using RIntroduction of  "the alternate features search" using R
Introduction of "the alternate features search" using RSatoshi Kato
 
ECMAScript6による関数型プログラミング
ECMAScript6による関数型プログラミングECMAScript6による関数型プログラミング
ECMAScript6による関数型プログラミングTanUkkii
 
Clojure programming-chapter-2
Clojure programming-chapter-2Clojure programming-chapter-2
Clojure programming-chapter-2Masao Kato
 
おいしいLisp
おいしいLispおいしいLisp
おいしいLispKent Ohashi
 
これからの「言語」の話をしよう ―― 未来を生きるためのツール
これからの「言語」の話をしよう ―― 未来を生きるためのツールこれからの「言語」の話をしよう ―― 未来を生きるためのツール
これからの「言語」の話をしよう ―― 未来を生きるためのツールNobuhisa Koizumi
 
Control.Arrow
Control.ArrowControl.Arrow
Control.Arrowharu haru
 
Replace Output Iterator and Extend Range JP
Replace Output Iterator and Extend Range JPReplace Output Iterator and Extend Range JP
Replace Output Iterator and Extend Range JPAkira Takahashi
 
Deep learning Libs @twm
Deep learning Libs @twmDeep learning Libs @twm
Deep learning Libs @twmYuta Kashino
 
Fork/Join Framework。そしてLambdaへ。
Fork/Join Framework。そしてLambdaへ。Fork/Join Framework。そしてLambdaへ。
Fork/Join Framework。そしてLambdaへ。Yuichi Sakuraba
 
すごいHaskell読書会#10
すごいHaskell読書会#10すごいHaskell読書会#10
すごいHaskell読書会#10Shin Ise
 
Nagoya.R #11 入門者講習
Nagoya.R #11 入門者講習Nagoya.R #11 入門者講習
Nagoya.R #11 入門者講習Yusaku Kawaguchi
 
第三回ありえる社内勉強会 「いわががのLombok」
第三回ありえる社内勉強会 「いわががのLombok」第三回ありえる社内勉強会 「いわががのLombok」
第三回ありえる社内勉強会 「いわががのLombok」yoshiaki iwanaga
 
つくってあそぼ ラムダ計算インタプリタ
つくってあそぼ ラムダ計算インタプリタつくってあそぼ ラムダ計算インタプリタ
つくってあそぼ ラムダ計算インタプリタ京大 マイコンクラブ
 

Semelhante a 【Topotal輪読会】JavaScript で学ぶ関数型プログラミング 4 章 (20)

【Topotal輪読会】JavaScript で学ぶ関数型プログラミング 2 章
【Topotal輪読会】JavaScript で学ぶ関数型プログラミング 2 章【Topotal輪読会】JavaScript で学ぶ関数型プログラミング 2 章
【Topotal輪読会】JavaScript で学ぶ関数型プログラミング 2 章
 
JavaScript 講習会 #1
JavaScript 講習会 #1JavaScript 講習会 #1
JavaScript 講習会 #1
 
FP習熟度レベルとFSharpxのIteratee
FP習熟度レベルとFSharpxのIterateeFP習熟度レベルとFSharpxのIteratee
FP習熟度レベルとFSharpxのIteratee
 
Scalaで萌える関数型プログラミング[完全版]
Scalaで萌える関数型プログラミング[完全版]Scalaで萌える関数型プログラミング[完全版]
Scalaで萌える関数型プログラミング[完全版]
 
po-6. 繰り返し実行(ループ),ステップ実行
po-6. 繰り返し実行(ループ),ステップ実行po-6. 繰り返し実行(ループ),ステップ実行
po-6. 繰り返し実行(ループ),ステップ実行
 
Introduction of "the alternate features search" using R
Introduction of  "the alternate features search" using RIntroduction of  "the alternate features search" using R
Introduction of "the alternate features search" using R
 
ECMAScript6による関数型プログラミング
ECMAScript6による関数型プログラミングECMAScript6による関数型プログラミング
ECMAScript6による関数型プログラミング
 
Clojure programming-chapter-2
Clojure programming-chapter-2Clojure programming-chapter-2
Clojure programming-chapter-2
 
Dotnetconf2017
Dotnetconf2017Dotnetconf2017
Dotnetconf2017
 
おいしいLisp
おいしいLispおいしいLisp
おいしいLisp
 
これからの「言語」の話をしよう ―― 未来を生きるためのツール
これからの「言語」の話をしよう ―― 未来を生きるためのツールこれからの「言語」の話をしよう ―― 未来を生きるためのツール
これからの「言語」の話をしよう ―― 未来を生きるためのツール
 
Control.Arrow
Control.ArrowControl.Arrow
Control.Arrow
 
Replace Output Iterator and Extend Range JP
Replace Output Iterator and Extend Range JPReplace Output Iterator and Extend Range JP
Replace Output Iterator and Extend Range JP
 
JavaScript入門
JavaScript入門JavaScript入門
JavaScript入門
 
Deep learning Libs @twm
Deep learning Libs @twmDeep learning Libs @twm
Deep learning Libs @twm
 
Fork/Join Framework。そしてLambdaへ。
Fork/Join Framework。そしてLambdaへ。Fork/Join Framework。そしてLambdaへ。
Fork/Join Framework。そしてLambdaへ。
 
すごいHaskell読書会#10
すごいHaskell読書会#10すごいHaskell読書会#10
すごいHaskell読書会#10
 
Nagoya.R #11 入門者講習
Nagoya.R #11 入門者講習Nagoya.R #11 入門者講習
Nagoya.R #11 入門者講習
 
第三回ありえる社内勉強会 「いわががのLombok」
第三回ありえる社内勉強会 「いわががのLombok」第三回ありえる社内勉強会 「いわががのLombok」
第三回ありえる社内勉強会 「いわががのLombok」
 
つくってあそぼ ラムダ計算インタプリタ
つくってあそぼ ラムダ計算インタプリタつくってあそぼ ラムダ計算インタプリタ
つくってあそぼ ラムダ計算インタプリタ
 

【Topotal輪読会】JavaScript で学ぶ関数型プログラミング 4 章