Currying in perl
Upcoming SlideShare
Loading in...5
×
 

Currying in perl

on

  • 2,649 views

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

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

Statistics

Views

Total Views
2,649
Slideshare-icon Views on SlideShare
1,402
Embed Views
1,247

Actions

Likes
0
Downloads
0
Comments
0

3 Embeds 1,247

http://hokkaido.pm.org 1243
https://twitter.com 3
http://www.perl-hokkaido.org 1

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Currying in perl Currying in perl Presentation Transcript

    • CurryとHokkaido.pm 2013.3.9 hiratara FreakOut
    • 初代ベスト エルティニスト賞
    • “Hokkaido.pm Casual はじめました” by techno_nekoスープCurryが観客の心と胃袋をつかみ、初代ベストエルティニスト賞となりました!おめでとうございました!http://hachiojipm.org/?p=403
    • “Hokkaido.pm Casual はじめました” by techno_nekoスープCurryが観客の心と胃袋をつかみ、初代ベストエルティニスト賞となりました!おめでとうございました!http://hachiojipm.org/?p=403
    • Curryが ウケるっぽい
    • currying
    • カリー化とは• A × B→Cの関数を、A→(B→C)にする• hoge($x, $y) みたいな関数を curried_hoge($x)($y) みたいにする
    • カリー化と 部分適用は違うよ
    • 部分適用とは• A × B→Cの関数を、B→Cにする• hoge($x, $y) みたいな関数に3を適用して hoge_3($y) みたいにする
    • 誤用すると色々危ない
    • curry関数の実装sub curry { my $f = shift; sub { my $x = shift; sub { $f->($x, @_) }; };}
    • 再帰的にカリー化• hoge($x, $y, $z) みたいな関数は curried_hoge($x)($y, $z) じゃなく curried_hoge($x)($y)($z) みたいにしたい• A × B × C→D A→(B × C→D) A→(B→(C→D))
    • 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); };}
    • 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); };}
    • 使い方sub add { $_[0] + $_[1] + $_[2] }my $x = (curry_n 3, &add)->(3)(4)(5);
    • 使い方sub add { $_[0] + $_[1] + $_[2] } まとめたいmy $x = (curry_n 3, &add)->(3)(4)(5);
    • カレーをカレーで食べる
    • 新しい関数を作る*curried_curry_n = curry_n(2, &curry_n);*curry3 = curried_curry_n(3);my $x = curry3(&add)->(3)(4)(5);
    • 新しい関数を作る curry_nは2引数関数*curried_curry_n = curry_n(2, &curry_n);*curry3 = curried_curry_n(3);my $x = curry3(&add)->(3)(4)(5);
    • 新しい関数を作る curry_nは2引数関数*curried_curry_n = curry_n(2, &curry_n);*curry3 = curried_curry_n(3); 引数の数を部分適用して新しい関数にするmy $x = curry3(&add)->(3)(4)(5);
    • カリー化すると 部分適用しやすい*curry3 = curried_curry_n(3);*curry4 = curried_curry_n(4);*curry5 = curried_curry_n(5);*{“curry$_”} = curried_curry_n($_) for 3.. 10000000;
    • ほんとに引数の数ってわからないの?
    • ($$$)
    • I ♡ function prototyping
    • プロトタイプを使うsub parse_proto ($) { my $f = shift; my $proto = prototype $f; $proto =~ /^([&_+*$]|[[$@%&*]+]|[$@%&*])(.+)/ ? ($1, $2) : (undef, $proto);}
    • プロトタイプを使う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; }/;}
    • プロトタイプを使う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; }/;}
    • 使い方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;
    • 使い方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; かっこなくてもよい
    • One more function prototyping
    • 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 *$$
    • currying builtinsuse 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;
    • currying builtinsuse 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; かっこなくてもよい
    • まとめ• カリー化すると部分適用しやすい• &CORE::xxx によりさらに便利に• プロトタイプ使うと隣の同僚に DISられる