currying in perl

34
CurryHokkaido.pm 2013.3.9 hiratara FreakOut

Upload: masahiro-honma

Post on 11-Jun-2015

2.399 views

Category:

Technology


0 download

DESCRIPTION

http://www.slideshare.net/hiratara/hokkaidopm-17020206 の本物の方。

TRANSCRIPT

Page 1: Currying in perl

CurryとHokkaido.pm2013.3.9 hiratara

FreakOut

Page 2: Currying in perl

初代ベストエルティニスト賞

Page 3: Currying in perl

“Hokkaido.pm Casual はじめました” by techno_neko

スープCurryが観客の心と胃袋をつかみ、初代ベストエルティニスト賞となりました!おめでとうございました!http://hachiojipm.org/?p=403

Page 4: Currying in perl

“Hokkaido.pm Casual はじめました” by techno_neko

スープCurryが観客の心と胃袋をつかみ、初代ベストエルティニスト賞となりました!おめでとうございました!http://hachiojipm.org/?p=403

Page 5: Currying in perl

Curryがウケるっぽい

Page 6: Currying in perl

currying

Page 7: Currying in perl

カリー化とは

• A × B→Cの関数を、A→(B→C)にする

• hoge($x, $y) みたいな関数をcurried_hoge($x)($y) みたいにする

Page 8: Currying in perl

カリー化と部分適用は違うよ

Page 9: Currying in perl

部分適用とは

• A × B→Cの関数を、B→Cにする

• hoge($x, $y) みたいな関数に3を適用してhoge_3($y) みたいにする

Page 10: Currying in perl

誤用すると色々危ない

Page 11: Currying in perl

curry関数の実装sub curry { my $f = shift; sub { my $x = shift; sub { $f->($x, @_) }; };}

Page 12: Currying in perl

再帰的にカリー化• hoge($x, $y, $z) みたいな関数は

curried_hoge($x)($y, $z) じゃなくcurried_hoge($x)($y)($z) みたいにしたい

• A × B × C→DA→(B × C→D)A→(B→(C→D))

Page 13: Currying in perl

curry_n関数の実装sub curry_n { my ($n, $f) = @_; $n <= 1 ? $f : sub { my $x = shift; my $fx = curry($f)->($x); curry_n($n - 1, $fx); };}

Page 14: Currying in perl

curry_n関数の実装sub curry_n { my ($n, $f) = @_; $n <= 1 ? $f : sub { my $x = shift; my $fx = curry($f)->($x); curry_n($n - 1, $fx); };}

引数の個数が必要

Page 15: Currying in perl

使い方

sub add { $_[0] + $_[1] + $_[2] }

my $x = (curry_n 3, \&add)->(3)(4)(5);

Page 16: Currying in perl

使い方

sub add { $_[0] + $_[1] + $_[2] }

my $x = (curry_n 3, \&add)->(3)(4)(5);まとめたい

Page 17: Currying in perl

カレーをカレーで食べる

Page 18: Currying in perl

新しい関数を作る

*curried_curry_n = curry_n(2, \&curry_n);*curry3 = curried_curry_n(3);

my $x = curry3(\&add)->(3)(4)(5);

Page 19: Currying in perl

新しい関数を作る

*curried_curry_n = curry_n(2, \&curry_n);*curry3 = curried_curry_n(3);

my $x = curry3(\&add)->(3)(4)(5);

curry_nは2引数関数

Page 20: Currying in perl

新しい関数を作る

*curried_curry_n = curry_n(2, \&curry_n);*curry3 = curried_curry_n(3);

my $x = curry3(\&add)->(3)(4)(5);

curry_nは2引数関数

引数の数を部分適用して新しい関数にする

Page 21: Currying in perl

カリー化すると部分適用しやすい

*curry3 = curried_curry_n(3);*curry4 = curried_curry_n(4);*curry5 = curried_curry_n(5);

*{“curry$_”} = curried_curry_n($_) for 3.. 10000000;

Page 22: Currying in perl

ほんとに引数の数ってわからないの?

Page 23: Currying in perl

($$$)

Page 24: Currying in perl

I ♡ function prototyping

Page 25: Currying in perl

プロトタイプを使う

sub parse_proto ($) { my $f = shift; my $proto = prototype $f; $proto =~ /^([&_+*\$]|\\\[[\$@%&*]+\]|\\[\$@%&*])(.+)/ ? ($1, $2) : (undef, $proto);}

Page 26: Currying in perl

プロトタイプを使うsub curry_proto_n ($) { my $f = shift; my ($p, $ps) = parse_proto $f;

! $p ? $f : eval qq/sub ($p) { my \$x = shift; my \$fx = sub ($ps) { \$f->(\$x, \@_) }; curry_proto_n \$fx; }/;}

Page 27: Currying in perl

プロトタイプを使うsub curry_proto_n ($) { my $f = shift; my ($p, $ps) = parse_proto $f;

! $p ? $f : eval qq/sub ($p) { my \$x = shift; my \$fx = sub ($ps) { \$f->(\$x, \@_) }; curry_proto_n \$fx; }/;}

Page 28: Currying in perl

使い方sub add ($$$) { $_[0] + $_[1] + $_[2] }

my $x = (curry_proto_n \&add)->(3)(4)(5);

BEGIN { *add10 = (curry_proto \&add)->(10) }my $x = add10 3, 4;

Page 29: Currying in perl

使い方sub add ($$$) { $_[0] + $_[1] + $_[2] }

my $x = (curry_proto_n \&add)->(3)(4)(5);

BEGIN { *add10 = (curry_proto \&add)->(10) }my $x = add10 3, 4;

かっこなくてもよい

Page 30: Currying in perl

One more function prototyping

Page 31: Currying in perl

Pod::Functions% perl -MPod::Functions -e 'eval { print $_, "\t", +(prototype "CORE::$_"), "\n" } for keys %Flavor'...getgrgid $connect *$dbmopen \%$$link $$rand ;$dbmclose \%msgsnd $$$umask ;$sleep ;$seek *$$

Page 32: Currying in perl

currying builtins

use 5.16.2;my $x = (curry_proto_n \&CORE::substr)->("abcde")(1)(2);

BEGIN { *substr_abcde = (curry_proto \&CORE::substr)->("abcde");}my $y = substr_abcde 1, 2;

Page 33: Currying in perl

currying builtins

use 5.16.2;my $x = (curry_proto_n \&CORE::substr)->("abcde")(1)(2);

BEGIN { *substr_abcde = (curry_proto \&CORE::substr)->("abcde");}my $y = substr_abcde 1, 2;

かっこなくてもよい

Page 34: Currying in perl

まとめ

• カリー化すると部分適用しやすい

• \&CORE::xxx によりさらに便利に

• プロトタイプ使うと隣の同僚にDISられる