• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Arrows in perl
 

Arrows in perl

on

  • 1,679 views

Arrowsの説明です。

Arrowsの説明です。

Statistics

Views

Total Views
1,679
Views on SlideShare
1,672
Embed Views
7

Actions

Likes
1
Downloads
4
Comments
0

4 Embeds 7

http://a0.twimg.com 3
http://paper.li 2
http://twicli.neocat.jp 1
http://us-w1.rockmelt.com 1

Accessibility

Upload Details

Uploaded via as Apple Keynote

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
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • 【5分】\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • 【10分】\n
  • \n
  • 黄色の部分が関数ではなく型なのがポイント。\n
  • \n
  • \n
  • 結合則を満たすような定義をしておいた方が厳密だし使いやすい\n
  • \n
  • 【15分】\n
  • \n
  • 任意のアローに対して同じ実装が利用可能。抽象化の効力。\n
  • 任意のアローに対して同じ実装が利用可能。抽象化の効力。\n
  • \n
  • \n
  • \n
  • 【20分】\n
  • \n
  • \n
  • \n
  • モナドを型パラメータとして扱うためのおまじない\n
  • returnやbindをarrowの言葉に翻訳してるだけ\n
  • さっきの図を元に実装。mapの辺りは型をそろえるおまじない\n
  • 【25分】よくある0除算の例\n
  • よくある0除算の例\n
  • \n
  • 上は自己関手圏。下はProfunctorの圏。下の方が遥かに難しくてよくわからない。特に ⊗の定義\n
  • \n
  • \n
  • \n
  • \n

Arrows in perl Arrows in perl Presentation Transcript

  • Arrows in Perl2011.12.10 hiratara
  • d.hatena.ne.jp/hirataratwitter.com/hirataraPerl
  • d.hatena.ne.jp/hirataratwitter.com/hirataraPerl
  • PerlHaskell
  • PerlHaskell
  • PerlHaskell
  • PerlHaskell
  • 10/18 YAPC::Asia 2011Monads in Perl Perl Monad Future ( JSDeferred)
  • 10/18 YAPC::Asia 2011Monads in Perl Perl Monad Future ( JSDeferred)
  • 10/18 YAPC::Asia 2011Monads in Perl Perl Monad Future ( JSDeferred)
  • Data::Monadmy $result = Data::Monad::Base::Sugar::for { pick my $x => sub { scalar_list 1 .. 100 }; pick my $y => sub { scalar_list $x .. 100 }; pick my $z => sub { scalar_list $y .. ($x + $y > 100 ? 100 : $x + $y) }; satisfy { $x**2 + $y**2 == $z**2 }; yield { $x, $y, $z }};
  • return >>=return :: a -> m a>>= :: m a -> (a -> m b) -> m breturn >>=
  • ma mb mb mc ma mc f >=> g == f >=> ga b b c a cma ma mb ma mb return >=> f == fa a b a b
  • (2) 2 fmap return joinfmap :: a -> b -> (m a -> m b)join :: m (m a) -> m a
  • (3)
  • η⊗id id⊗ηI⊗M M⊗M M⊗I μ λ ρ M
  • ( ) 0×id id×0(*, n) (0, n) (n, 0) (n, *) (+) π’ π n
  • ( ) fmap return returnid.fmap fmap.fmap fmap.id join id id fmap
  • ( ) fmap return returnid.fmap fmap.fmap fmap.id join id id fmap
  • ArrowsJohn Hughes 2000
  • Monad Arrow (Haskell ) mb f aArrows f :: m b c b a
  • Arrowsarr >>> first ↝arr :: a -> b -> (a ↝ b)>>> :: (a ↝ b) -> (b ↝ c) -> (a ↝ c)first :: (a ↝ b) -> (a × c ↝ b × c)
  • Arrow package Arrow; sub arr { my ($class, $code) = @_; die "not implemented"; } sub first { my $self = shift; die "not implemented"; } sub next { my ($self, $arrow) = @_; die "not implemented"; }
  • first a↝b a b >>> arr ↝a f b a arr f :: a ↝ b b g arr arr f >>> arr g :: a ↝ c arr g :: b ↝ c g.f c c
  • first Arrow ↝ a c a×cf :: a↝b g :: c↝d f *** g :: a×c↝b×d b d b×d
  • (f *** g) >>> (f’ *** g’) (f >>> f’) *** (g >>> g’) f g f g f’ g’ f’ g’
  • (f *** g) >>> (f’ *** g’) (f >>> f’) *** (g >>> g’) f g f g f’ g’ f’ g’
  • premonoidal category f ⋉ id = first f a×b a×b id ⋊ f = second f f ⋉ id a’×b (f>>>f’) ⋉ id f’ ⋉ id a’’×b a’’×b
  • premonoidal category f ⋉ id = first f a×b a×b id ⋊ f = second f f ⋉ id a’×b (f>>>f’) ⋉ id f’ ⋉ id a’’×b a’’×b
  • central f *** g ≡ first f >>> second g first f >>> second - = second - >>> first f first - >>> second f = second f >>> first - f central arr f central f |x g ≡ first f >>> second (arr g) ( 10.2)
  • Freyd category premonoidal category(central central ) a -> b Arrow a ↝ b arr Freyd category
  • first ( )
  • second *** sub second { my $self = shift; my $swap = (ref $self)->arr(sub { $_[1], $_[0] }); $swap->next($self->first)->next($swap); } sub parallel { my ($self, $arrow) = @_; $self->first->next($arrow->second); } fst f >>> snd g id g C C D f id A B B
  • &&& sub split { my ($self, $arrow) = @_; (ref $self)->arr(sub { my $args = [@_]; $args, $args; })->next($self->parallel($arrow)); } A A arr id arr id arr <id, id> f g A arr π A×A arr π’ A f &&&g f g f *** g arr π arr π’B arr π B×C arr π’ C B B×C C
  • (1):Perlf : A×B → C×D
  • (1):first :: a × b × c -> d × e -> (a × b × c × y × z -> d × e × y × z) 5
  • (1): f (@v1 ) sub first { my $self = shift; (ref $self)->arr(sub { my (@v1, @v2) = @_; $self->(@v1), @v2; }); } first 2(A × B) × (C × D)
  • package Arrow::Subroutine;use parent qw/Arrow/;sub arr { my ($class, $code) = @_; bless $code, $class;}sub first { my $self = shift; (ref $self)->arr(sub { my ($v1, $v2) = @_; [$self->(@$v1)], $v2; });}sub next { my ($self, $arrow) = @_; (ref $self)->arr(sub { $arrow->($self->(@_)) });}
  • my $arr3 = Arrow::Subroutine->arr(sub { 3 });my $arr4 = Arrow::Subroutine->arr(sub { 4 });my $arrow_add = Arrow::Subroutine->arr(sub { $_[0]->[0] + $_[1]->[0];});my $arr3_plus_4 = $arr3->split($arr4)->next($arrow_add);print $arr3_plus_4->(), "n"; 3 π () 3 &&& 4 + Int×Int Int π’ 4
  • (2): >>> arrfirst
  • first a π a×c π’ c f f×return return π π’ mb mb×mc mc φ m(b×c)
  • package Arrow::Kleisli;use parent qw/Arrow/;sub _safe_name($) { my $name = shift; $name =~ s|::|__|g; return "__$name";}sub new_class { my $class = shift; my ($monad) = @_; my $class_name = "$class::" . _safe_name($monad); unless ($class_name->isa($class)) { no strict qw/refs/; @{"$class_name::ISA"} = ($class); *{"$class_name::monad"} = sub { $monad }; *{"$class_name::new_class"} = sub { die "Dont call the new_class() method from sub classes."; }; } return $class_name;}sub monad { die "Implement this method in sub classes" }...
  • sub new { my ($class, $kleisli) = @_; bless $kleisli, $class;}sub arr { my ($class, $code) = @_; $class->new(sub { $class->monad->unit($code->(@_)); });}sub next { my ($self, $arrow) = @_; (ref $self)->new(sub { my @v = @_; $self->(@v)->flat_map($arrow); });}
  • sub first { my $self = shift; my $class = (ref $self); my $monad = $class->monad; $class->new(sub { my ($args1, $args2) = @_; $monad->sequence( $self->(@$args1)->map(sub {[@_]}), $monad->unit(@$args2)->map(sub {[@_]}), ); });}
  • arr 10 arr π () arr 10 &&& arr 2 div Int×Int Int arr π’ arr 2div :: Int×Int ↝ Int = Int×Int → Maybe Int
  • my $class = Arrow::Kleisli->new_class(Data::Monad::Maybe);my $arrow10 = $class->arr(sub { 10 });my $arrow2 = $class->arr(sub { 2 });my $arrow_div = $class->new(sub { $_[1][0] == 0 ? nothing : just ($_[0][0] / $_[1][0]);});my $arrow10_div_2 = $arrow10->split($arrow2)->next($arrow_div);my $maybe = $arrow10_div_2->();print $maybe->is_nothing ? NOTHING : $maybe->value;print "n";
  • ArrowsStream Arrows
  • :Arrows mm join return m id >>> arr ↝⊗↝ ↝ Hom
  • ( ) arr⊗id id⊗arrHom⊗↝ ↝⊗↝ ↝⊗Hom >>> λ ρ ↝
  • ArrowsfirstLL Arrows
  • http://d.hatena.ne.jp/m-hiyama/20111107/1320624410