SlideShare a Scribd company logo
1 of 92
Download to read offline
Monads in Perl
hiratara <hira.tara@gmail.com>
About me

d.hatena.ne.jp/hiratara
twitter.com/hiratara
working as a Perl programmer
a fan of Mathematics
a reporter of this YAPC
What are Monads?
Actually, monads are
not anything special.
Category theory helps
 your understanding.
An arrow is a function
                                   split
               Regex, Str, Int                [Str]

                  @str = split /$regex/, $str, $n

      length
Str                Int

$len = length $str
Or represents a method
            new
ClassName              CGI

     $cgi = CGI->new

                             param
                  CGI, Str              [Str]

                  @values = $cgi->param($str)
Connecting two arrows

          *
     f         g



*                  *
Connecting two arrows

                        *
             f                   g

                       f;g
     *                                 *
                             sub f;g {
sub f;g { g(f(@_)) }   or       my @v = f(@_);
                                g(@v)
                             }
The 2 laws of arrows
1) Identity
      sub id { @_ }


                f;id

id          f          id


     id;f
2) Associativity
        f;(g;h)




f           g          h




        (f;g);h
Monad consists of
 Kleisli arrows
Call a diagonal arrow
    a Kleisli arrow

M(*)            M(*)
        f


 *                *
Composition of
             2 Kleisli arrows


M(*)         M(*)        M(*)
       f            g


 *            *            *
Composition of
             2 Kleisli arrows
       sub f>=>g { f(@_)->flat_map(&g) }


M(*)                M(*)                   M(*)
                  f>=>g


 *                      *                   *
The 2 laws of
          Kleisli arrows
(i.e. Monad laws)
1) Identity
               sub unit { ... }

                                            M(*)
                          f>=>unit

               *
               M(*)           M(*)          M(*)
    unit              f              unit
*               *              *
                              M(*)
    unit>=>f

*
2) Associativity
         f>=>(g>=>h)               M(*)


*                                  M(*)
          M(*)



*         *
          M(*)          M(*)       M(*)
    f            g             h

*         *              *
                        M(*)       M(*)



*         (f>=>g)>=>h    *         M(*)
Consider >=> as
   “a programmable ;“
Monads are made of
             3 things
1. Nested types M
M(M(*))   M(M(*))   M(M(*))   M(M(*))   M(M(*))




M(*)       M(*)       M(*)     M(*)       M(*)




  *          *         *         *         *
2. A set of arrows
                 to wrap values
M(M(*))      M(M(*))        M(M(*))         M(M(*))        M(M(*))

      unit           unit            unit          unit

M(*)          M(*)            M(*)           M(*)            M(*)

      unit          unit             unit           unit

  *             *              *               *              *
3. The operation
            to lift up arrows
M(M(*))   M(M(*))   M(M(*))    M(M(*))    M(M(*))

  flat_map     flat_map     flat_map flat_map

M(*)        M(*)        M(*)     M(*)       M(*)

  flat_map    flat_map    flat_map flat_map

  *          *           *        *          *
POINT: M extends values
M(*)
                         $m5            $m3
           $m1
                  $m2             $m4




 *
       1         “foo”         undef          $obj
POINT: M extends values
M(*)
                           $m5                      $m3
           $m1
                    $m2                     $m4
     unit(1)     unit(“foo”)          unit(undef)    unit($obj)


                               unit
 *
       1           “foo”                undef             $obj
ex). List
[*]
                           []   [$obj1, $obj2, $obj3]
       [1, 2, 3]
              [“foo”, “bar”] [undef, undef]
      [1]          [“foo”]      [undef]       [$obj]



*
      1            “foo”        undef         $obj
Monads provide
extended values and
  its computations
Let’s implement
         the List Monad
All you have to do is
define a type and unit
     and flat_map.
Implementation of List Monad

     sub unit { [$_[0]] }

     sub flat_map {
        my ($m, $f) = @_;
        [map { @{$f->($_)} } @$m];
     }
That's all we need!
Well, are you interested in
                   monads law?
The check is left as
                 an exercise :p
Simple usage of List monads

  [3, 5]                          [$n + 1, ..., $n + 6]




                      roll_dice
    $n

sub roll_dice { [map { $_[0] + $_ } 1 .. 6] }
Simple usage of List monads
                       roll_dice’     [4, 5, ..., 9,
    [3, 5]
                                      6, 7, ..., 11]

             flat_map




sub roll_dice’ { flat_map $_[0] => &roll_dice }
When we define a monad,
     it comes with
  2 relative functions.
1. map

         map(go_to_jail)
[3, 5]                     [0, 0]


                map


           go_to_jail
 $n                         0
1. map

             map(go_to_jail)
 [3, 5]                           [0, 0]
sub map_ {
   my ($m, $f) = @_;
                   map
   flat_map $m => sub { unit($f->($_[0])) };
}
               go_to_jail
   $n                             0
2. flatten

M(M(M(*)))   M(M(M(*)))   M(M(M(*)))   M(M(M(*)))   M(M(M(*)))

   flatten        flatten       flatten       flatten       flatt
M(M(*))      M(M(*))      M(M(*))      M(M(*))      M(M(*))
   flatten        flatten       flatten       flatten       flatt

 M(*)         M(*)          M(*)        M(*)          M(*)


   *             *             *           *             *
Implementation of
      flatten

              flatten
M(M(*))                M(*)

        flat_map
                  id

 M(*)                   *
Implementation of
           flatten

                 flatten
sub flatten {
     M(M(*))              M(*)
   my $m = shift;
   flat_map $m => &id;
          flat_map
}                    id

     M(*)                  *
flatten() has an
important role on
    monads.
Reduction of terms
   6       3            2        8
       +

       9                2        8
                    +

               11                8
                             +
                        19
flatten() plays the same role
        M       (M     (M   (M (*))))
            flatten

            M          (M (M (*)))
                     flatten

                 M          (M   (*))
                        flatten
                       M          (*)
Can you illustrate
another example of
     monads?
AnyEvent
Sample code of AE
my $cv = AE::cv;

http_get "http://yapcasia.org/2011/", sub {
   my ($data, $hdr) = @_;
   $cv->send($hdr->{'content-length'});
};

print $cv->recv;
Sample code of AE
my $cv = AE::cv;

http_get "http://yapcasia.org/2011/", sub {
   my ($data, $hdr) = @_;
   $cv->send($hdr->{'content-length'});
};

print $cv->recv;
$cv represents
a future value.
CondVar isn’t
     a normal value
# !! Can’t write in this way !!

sub some_callback {
   my $cv = shift;

    print $cv, “n”;
}
Retrieve the value from $cv


   sub some_callback {
      my $cv = shift;

       print $cv->recv, “n”;
   }
Run it !

% perl ./my_great_app.pl
EV: error in callback (ignoring):
AnyEvent::CondVar: recursive blocking wait
attempted at ./my_great_app.pl line 9836
You must use cb().
 sub some_callback {
    my $cv = shift;

     $cv->cb(sub {
         print $_[0]->recv, "n";
     });
 }
Use cb()
sub some_callback {
   my $cv = shift;

    $cv->cb(sub {
        my $cv = next_task1 $_[0]->recv;
        $cv->cb(sub {
            my $cv = next_task2 $_[0]->recv;
            ...
        });
    });
}
Use cb()
sub some_callback {
   my $cv = shift;

    $cv->cb(sub {
        my $cv = next_task1 $_[0]->recv;
        $cv->cb(sub {
            my $cv = next_task2 $_[0]->recv;
            $cv->cb(sub {
                my $cv = next_task3 $_[0]->recv;
                $cv->cb(sub {
                    my $cv = next_task4 $_[0]->recv;
                    ...
                });
            });
        });
    });
}
$cv->cb(sub {
   my $cv = next_task2 $_[0]->recv;
   $cv->cb(sub {


              Use cb()
      my $cv = next_task3 $_[0]->recv;
      $cv->cb(sub {
          my $cv = next_task4 $_[0]->recv;
          $cv->cb(sub {
              my $cv = next_task5 $_[0]->recv;
              $cv->cb(sub {
                  my $cv = next_task6 $_[0]->recv;
                  $cv->cb(sub {
                      my $cv = next_task7 $_[0]->recv;
                      $cv->cb(sub {
                          my $cv = next_task8 $_[0]->recv;
                          $cv->cb(sub {
                              my $cv = next_task9 $_[0]->recv;
                              $cv->cb(sub {
                                  my $cv = next_task10 $_[0]->recv;
                                  ...
                              });
                          });
                      });
                  });
              });
          });
A callback-hell
Coro solves
              the problem
Use Coro::AnyEvent
sub some_callback {
   my $cv = shift;

    async {
       my $cv1 = next_task1($cv->recv);
       my $cv2 = next_task2($cv1->recv);
       my $cv3 = next_task3($cv2->recv);
       my $cv4 = next_task4($cv3->recv);
       ...
    };
}
Looks perfect!
Though, Coro does
     some deep magic
Organize the chaos
 by the monad pattern
Let’s define a type and
unit and flat_map
AE::CondVar is the type
# CondVar(STR)
my $cv = AE::cv;
$cv->send(‘Normal value’);

# CondVar(CondVar(Str))
my $cvcv = AE::cv;
$cvcv->send($cv);

# CondVar(CondVar(CondVar(Str)))
my $cvcvcv = AE::cv;
$cvcvcv->send($cvcv);
Which CondVar objs
 do normal values
  correspond to?
We can retrieve a normal
  value without delay
 sub unit {
    my @values = @_

     my $cv = AE::cv;
     $cv->send(@values);

     return $cv;
 }
Think about flat_map()


   “foo”                   “Hi, $_[0]”
after 3 sec                after 2 sec

        flat_map
                  say_hi

   $_[0]                    *
Think about flat_map()

$name->flat_map(&say_hi)

                    5 sec         “Hi, foo”

say_hi                      2 sec “Hi, foo”

$name      3 sec    “foo”
Implementation of
         flat_map
sub flat_map {
   my ($cv, $f) = @_;

    $cv->cb(sub {
       my @values = $_[0]->recv;
       my $cv = $f->(@values);
       ...
    })

    return ...
}
Implementation of
            flat_map
sub flat_map {
   my ($cv, $f) = @_;

    my $result = AE::cv;
    $cv->cb(sub {
        my @values = $_[0]->recv;
        my $cv = $f->(@values);
        $cv->cb(sub { $result->send($_[0]->recv) });
    });

    return $result;
}
A monad comes with
  map and flatten
Use the CondVar monad
$cv
 ∋




CV(*)                  CV(*)                CV(*)

flat_map                flat_map




          next_task1           next_task2
  *                      *                    *
Use the CondVar monad
$cv
        sub some_callback {
 ∋




           my $cv = shift;
CV(*)                         CV(*)          CV(*)
        $cv->flat_map(&next_task1)
flat_map                  flat_map
           ->flat_map(&next_task2)
           ->flat_map(&next_task3)
           ->flat_map(&next_task4)
           ->...
      } next_task1              next_task2
  *                             *              *
The CV monad has the
continuation monad structure
   newtype Cont r a = Cont {
      runCont :: (a -> r) -> r
   }
   runCont cv $ v -> print v


   $cv->cb(sub {
       my @v = $_[0]->recv;
       print @v;
   });
The CV monad also has the
  Either monad structure


data Either String a = Left String | Right a



(my $right = AE::cv)->send(“A right value”);
(my $left = AE::cv)->croak(“A left value”);
Handle exceptions in
     flat_map
Left l >>= _ = Left l
Right r >>= f = f r

...
my $result = AE::cv;
$cv->cb(sub {
    my @r = eval { $_[0]->recv };
    return $result->croak($@) if $@;
    my $cv = $f->(@r);
    ...
});
...
Define subs to handle errors

  sub fail {
     my @values = @_

      my $cv = AE::cv;
      $cv->croak(@values);

      return $cv;
  }
Define subs to handle errors
   sub catch {
      ...
      my $result = AE::cv;
      $cv->cb(sub {
          my @r = eval { $_[0]->recv };
          return $result->send(@r) if @r;
          my $cv = $f->($@);
          ...
      });
      ...
A sample code of catch
unit(1, 0)->flat_map(sub {
    my @v = eval { $_[0] / $_[1] };
    $@ ? fail($@) : unit(@v);
})->catch(sub {
    my $exception = shift;
    $exception =~ /Illegal division/
        ? unit(0)           # recover from errors
        : fail($exception); # rethrow
})->flat_map(sub {
    ...
});
Does everything
              go well?
NO
Concurrency


CV(*), CV(*)            CV(*, *)
Concurrency


               sequence
CV(*), CV(*)              CV(*, *)
There’re no alchemy.


                 Oo
CV(*, *)              ps!   CV(*, *)

           map

                  id
  *, *                        *, *
Define it directly
sub sequence {
   my ($cv1, $cv2) = @_;

    $cv1->flat_map(sub {
        my @v1 = @_;
        $cv2->flat_map(sub {
            my @v2 = @_;
            unit(@v1, @v2);
        });
    });
}
Use nested blocks to handle
   more than one monad
  $cv1->flat_map(sub {
     my @v1 = @_;
        $cv2->flat_map(sub {
           my @v2 = @_;
           $cv3->flat_map(sub {
              my @v3 = @_;
              $cv4->flat_map(sub {
                 my @v4 = @_;
                $cv5->flat_map(sub {
                    my @v5 = @_;
                    ...
Back to the hell
Haskell’s do expression

do v1   <-   cv1
  v2    <-   cv2
  v3    <-   cv3
  v4    <-   cv4
  ...

  return (v1, v2, v3, v4, ...)
The for comprehension

Data::Monad::Base::Sugar::for {
   pick my @v1 => sub { $cv1 };
   pick my @v2 => sub { $cv2 };
   pick my @v3 => sub { $cv3 };
   pick my @v4 => sub { $cv4 };
   ...

     yield { @v1, @v2, @v3, @v4, ... };
};
ex). Better implementation of
          sequence
   sub sequence {
      my ($cv1, $cv2) = @_;

       $cv1->flat_map(sub {
           my @v1 = @_;
           $cv2->flat_map(sub {
               my @v2 = @_;
               unit(@v1, @v2);
           });
       });
   }
ex). Better implementation of
          sequence
   sub sequence {
      my ($cv1, $cv2) = @_;

       Data::Monad::Base::Sugar::for {
          pick my @v1 => sub { $cv1 };
          pick my @v2 => sub { $cv2 };
          yield { @v1, @v2 };
       };
   }
Conclusion

   A monad is made of a type,
   flat_map, unit
   Consider AE::cv as a monad
   CondVar monads save you from a
   callback hell
https://github.com/hiratara/p5-Data-Monad

More Related Content

What's hot

119 Powerpoint 2.6
119 Powerpoint 2.6119 Powerpoint 2.6
119 Powerpoint 2.6
Jeneva Clark
 
2015 02-18 xxx-literalconvertible
2015 02-18 xxx-literalconvertible2015 02-18 xxx-literalconvertible
2015 02-18 xxx-literalconvertible
Taketo Sano
 
C - aptitude3
C - aptitude3C - aptitude3
C - aptitude3
Srikanth
 
Composicion de funciones
Composicion de funcionesComposicion de funciones
Composicion de funciones
Paito Sarauz
 
5.1 analysis of function i
5.1 analysis of function i5.1 analysis of function i
5.1 analysis of function i
dicosmo178
 
รายงานคอม
รายงานคอมรายงานคอม
รายงานคอม
Areeya Onnom
 
รายงานคอม
รายงานคอมรายงานคอม
รายงานคอม
Areeya Onnom
 
Funct format sql_statement.c
Funct format sql_statement.cFunct format sql_statement.c
Funct format sql_statement.c
albertinous
 

What's hot (20)

My sql cheat sheet
My sql cheat sheetMy sql cheat sheet
My sql cheat sheet
 
Objective-C for Java developers
Objective-C for Java developersObjective-C for Java developers
Objective-C for Java developers
 
119 Powerpoint 2.6
119 Powerpoint 2.6119 Powerpoint 2.6
119 Powerpoint 2.6
 
Google collections api an introduction
Google collections api   an introductionGoogle collections api   an introduction
Google collections api an introduction
 
2015 02-18 xxx-literalconvertible
2015 02-18 xxx-literalconvertible2015 02-18 xxx-literalconvertible
2015 02-18 xxx-literalconvertible
 
C - aptitude3
C - aptitude3C - aptitude3
C - aptitude3
 
Python Cheat Sheet
Python Cheat SheetPython Cheat Sheet
Python Cheat Sheet
 
밑바닥부터 시작하는 의료 AI
밑바닥부터 시작하는 의료 AI밑바닥부터 시작하는 의료 AI
밑바닥부터 시작하는 의료 AI
 
Composicion de funciones
Composicion de funcionesComposicion de funciones
Composicion de funciones
 
6. binary tree
6. binary tree6. binary tree
6. binary tree
 
133467 p1a9
133467 p1a9133467 p1a9
133467 p1a9
 
5.1 analysis of function i
5.1 analysis of function i5.1 analysis of function i
5.1 analysis of function i
 
The Ring programming language version 1.10 book - Part 127 of 212
The Ring programming language version 1.10 book - Part 127 of 212The Ring programming language version 1.10 book - Part 127 of 212
The Ring programming language version 1.10 book - Part 127 of 212
 
Monads from Definition
Monads from DefinitionMonads from Definition
Monads from Definition
 
รายงานคอม
รายงานคอมรายงานคอม
รายงานคอม
 
รายงานคอม
รายงานคอมรายงานคอม
รายงานคอม
 
My favorite slides
My favorite slidesMy favorite slides
My favorite slides
 
Funct format sql_statement.c
Funct format sql_statement.cFunct format sql_statement.c
Funct format sql_statement.c
 
Alg2 lesson 7-8
Alg2 lesson 7-8Alg2 lesson 7-8
Alg2 lesson 7-8
 
Alg2 lesson 7-8
Alg2 lesson 7-8Alg2 lesson 7-8
Alg2 lesson 7-8
 

Similar to Monads in perl

Monad Transformers In The Wild
Monad Transformers In The WildMonad Transformers In The Wild
Monad Transformers In The Wild
StackMob Inc
 
Introduction to Monads in Scala (2)
Introduction to Monads in Scala (2)Introduction to Monads in Scala (2)
Introduction to Monads in Scala (2)
stasimus
 
#Import standard math functions from math import import .docx
#Import standard math functions from math import  import .docx#Import standard math functions from math import  import .docx
#Import standard math functions from math import import .docx
gertrudebellgrove
 
Datamining r 4th
Datamining r 4thDatamining r 4th
Datamining r 4th
sesejun
 
Modular Module Systems
Modular Module SystemsModular Module Systems
Modular Module Systems
league
 
Monads do not Compose
Monads do not ComposeMonads do not Compose
Monads do not Compose
Philip Schwarz
 
ML: A Strongly Typed Functional Language
ML: A Strongly Typed Functional LanguageML: A Strongly Typed Functional Language
ML: A Strongly Typed Functional Language
lijx127
 

Similar to Monads in perl (20)

The Essence of the Iterator Pattern (pdf)
The Essence of the Iterator Pattern (pdf)The Essence of the Iterator Pattern (pdf)
The Essence of the Iterator Pattern (pdf)
 
The Essence of the Iterator Pattern
The Essence of the Iterator PatternThe Essence of the Iterator Pattern
The Essence of the Iterator Pattern
 
Monad Transformers In The Wild
Monad Transformers In The WildMonad Transformers In The Wild
Monad Transformers In The Wild
 
Array
ArrayArray
Array
 
Introduction to Monads in Scala (2)
Introduction to Monads in Scala (2)Introduction to Monads in Scala (2)
Introduction to Monads in Scala (2)
 
Software Visualization 101+
Software Visualization 101+Software Visualization 101+
Software Visualization 101+
 
#Import standard math functions from math import import .docx
#Import standard math functions from math import  import .docx#Import standard math functions from math import  import .docx
#Import standard math functions from math import import .docx
 
Datamining r 4th
Datamining r 4thDatamining r 4th
Datamining r 4th
 
Modular Module Systems
Modular Module SystemsModular Module Systems
Modular Module Systems
 
Implementing Software Machines in C and Go
Implementing Software Machines in C and GoImplementing Software Machines in C and Go
Implementing Software Machines in C and Go
 
Part 7
Part 7Part 7
Part 7
 
Haskellで学ぶ関数型言語
Haskellで学ぶ関数型言語Haskellで学ぶ関数型言語
Haskellで学ぶ関数型言語
 
An Introduction to Part of C++ STL
An Introduction to Part of C++ STLAn Introduction to Part of C++ STL
An Introduction to Part of C++ STL
 
M.c.qs.- 3(functions & their graphs)
M.c.qs.- 3(functions & their graphs)M.c.qs.- 3(functions & their graphs)
M.c.qs.- 3(functions & their graphs)
 
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
 
Monads do not Compose
Monads do not ComposeMonads do not Compose
Monads do not Compose
 
Fp in scala with adts
Fp in scala with adtsFp in scala with adts
Fp in scala with adts
 
Software Visualization - Promises & Perils
Software Visualization - Promises & PerilsSoftware Visualization - Promises & Perils
Software Visualization - Promises & Perils
 
ML: A Strongly Typed Functional Language
ML: A Strongly Typed Functional LanguageML: A Strongly Typed Functional Language
ML: A Strongly Typed Functional Language
 
Go Course Day2
Go Course Day2Go Course Day2
Go Course Day2
 

More from Masahiro Honma

Stateモナドの解説 後編
Stateモナドの解説 後編Stateモナドの解説 後編
Stateモナドの解説 後編
Masahiro Honma
 
Stateモナドの解説 中編
Stateモナドの解説 中編Stateモナドの解説 中編
Stateモナドの解説 中編
Masahiro Honma
 

More from Masahiro Honma (20)

レンズ (ぶつかり稽古の没プレゼン)
レンズ (ぶつかり稽古の没プレゼン)レンズ (ぶつかり稽古の没プレゼン)
レンズ (ぶつかり稽古の没プレゼン)
 
すべてが@__kanになる
すべてが@__kanになるすべてが@__kanになる
すべてが@__kanになる
 
Types and perl language
Types and perl languageTypes and perl language
Types and perl language
 
Currying in perl
Currying in perlCurrying in perl
Currying in perl
 
カレーとHokkaidopm
カレーとHokkaidopmカレーとHokkaidopm
カレーとHokkaidopm
 
モナモナ言うモナド入門.tar.gz
モナモナ言うモナド入門.tar.gzモナモナ言うモナド入門.tar.gz
モナモナ言うモナド入門.tar.gz
 
モナモナ言うモナド入門
モナモナ言うモナド入門モナモナ言うモナド入門
モナモナ言うモナド入門
 
Perl saved a lady.
Perl saved a lady.Perl saved a lady.
Perl saved a lady.
 
Levenshtein Automata
Levenshtein AutomataLevenshtein Automata
Levenshtein Automata
 
20120526 hachioji.pm
20120526 hachioji.pm20120526 hachioji.pm
20120526 hachioji.pm
 
循環参照のはなし
循環参照のはなし循環参照のはなし
循環参照のはなし
 
Hachioji.pm in Machida の LT
Hachioji.pm in Machida の LTHachioji.pm in Machida の LT
Hachioji.pm in Machida の LT
 
ウヰスキーとPSGI
ウヰスキーとPSGIウヰスキーとPSGI
ウヰスキーとPSGI
 
モデルから知るGit
モデルから知るGitモデルから知るGit
モデルから知るGit
 
YAPCレポートの舞台裏
YAPCレポートの舞台裏YAPCレポートの舞台裏
YAPCレポートの舞台裏
 
Git入門
Git入門Git入門
Git入門
 
AnyEvent and Plack
AnyEvent and PlackAnyEvent and Plack
AnyEvent and Plack
 
Math::Category
Math::CategoryMath::Category
Math::Category
 
Stateモナドの解説 後編
Stateモナドの解説 後編Stateモナドの解説 後編
Stateモナドの解説 後編
 
Stateモナドの解説 中編
Stateモナドの解説 中編Stateモナドの解説 中編
Stateモナドの解説 中編
 

Recently uploaded

Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
panagenda
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
?#DUbAI#??##{{(☎️+971_581248768%)**%*]'#abortion pills for sale in dubai@
 

Recently uploaded (20)

MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectors
 
AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot ModelNavi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 

Monads in perl

  • 1. Monads in Perl hiratara <hira.tara@gmail.com>
  • 2. About me d.hatena.ne.jp/hiratara twitter.com/hiratara working as a Perl programmer a fan of Mathematics a reporter of this YAPC
  • 4. Actually, monads are not anything special.
  • 5. Category theory helps your understanding.
  • 6. An arrow is a function split Regex, Str, Int [Str] @str = split /$regex/, $str, $n length Str Int $len = length $str
  • 7. Or represents a method new ClassName CGI $cgi = CGI->new param CGI, Str [Str] @values = $cgi->param($str)
  • 9. Connecting two arrows * f g f;g * * sub f;g { sub f;g { g(f(@_)) } or my @v = f(@_); g(@v) }
  • 10. The 2 laws of arrows
  • 11. 1) Identity sub id { @_ } f;id id f id id;f
  • 12. 2) Associativity f;(g;h) f g h (f;g);h
  • 13. Monad consists of Kleisli arrows
  • 14. Call a diagonal arrow a Kleisli arrow M(*) M(*) f * *
  • 15. Composition of 2 Kleisli arrows M(*) M(*) M(*) f g * * *
  • 16. Composition of 2 Kleisli arrows sub f>=>g { f(@_)->flat_map(&g) } M(*) M(*) M(*) f>=>g * * *
  • 17. The 2 laws of Kleisli arrows (i.e. Monad laws)
  • 18. 1) Identity sub unit { ... } M(*) f>=>unit * M(*) M(*) M(*) unit f unit * * * M(*) unit>=>f *
  • 19. 2) Associativity f>=>(g>=>h) M(*) * M(*) M(*) * * M(*) M(*) M(*) f g h * * * M(*) M(*) * (f>=>g)>=>h * M(*)
  • 20. Consider >=> as “a programmable ;“
  • 21. Monads are made of 3 things
  • 22. 1. Nested types M M(M(*)) M(M(*)) M(M(*)) M(M(*)) M(M(*)) M(*) M(*) M(*) M(*) M(*) * * * * *
  • 23. 2. A set of arrows to wrap values M(M(*)) M(M(*)) M(M(*)) M(M(*)) M(M(*)) unit unit unit unit M(*) M(*) M(*) M(*) M(*) unit unit unit unit * * * * *
  • 24. 3. The operation to lift up arrows M(M(*)) M(M(*)) M(M(*)) M(M(*)) M(M(*)) flat_map flat_map flat_map flat_map M(*) M(*) M(*) M(*) M(*) flat_map flat_map flat_map flat_map * * * * *
  • 25. POINT: M extends values M(*) $m5 $m3 $m1 $m2 $m4 * 1 “foo” undef $obj
  • 26. POINT: M extends values M(*) $m5 $m3 $m1 $m2 $m4 unit(1) unit(“foo”) unit(undef) unit($obj) unit * 1 “foo” undef $obj
  • 27. ex). List [*] [] [$obj1, $obj2, $obj3] [1, 2, 3] [“foo”, “bar”] [undef, undef] [1] [“foo”] [undef] [$obj] * 1 “foo” undef $obj
  • 28. Monads provide extended values and its computations
  • 29. Let’s implement the List Monad
  • 30. All you have to do is define a type and unit and flat_map.
  • 31. Implementation of List Monad sub unit { [$_[0]] } sub flat_map { my ($m, $f) = @_; [map { @{$f->($_)} } @$m]; }
  • 32. That's all we need!
  • 33. Well, are you interested in monads law? The check is left as an exercise :p
  • 34. Simple usage of List monads [3, 5] [$n + 1, ..., $n + 6] roll_dice $n sub roll_dice { [map { $_[0] + $_ } 1 .. 6] }
  • 35. Simple usage of List monads roll_dice’ [4, 5, ..., 9, [3, 5] 6, 7, ..., 11] flat_map sub roll_dice’ { flat_map $_[0] => &roll_dice }
  • 36. When we define a monad, it comes with 2 relative functions.
  • 37. 1. map map(go_to_jail) [3, 5] [0, 0] map go_to_jail $n 0
  • 38. 1. map map(go_to_jail) [3, 5] [0, 0] sub map_ { my ($m, $f) = @_; map flat_map $m => sub { unit($f->($_[0])) }; } go_to_jail $n 0
  • 39. 2. flatten M(M(M(*))) M(M(M(*))) M(M(M(*))) M(M(M(*))) M(M(M(*))) flatten flatten flatten flatten flatt M(M(*)) M(M(*)) M(M(*)) M(M(*)) M(M(*)) flatten flatten flatten flatten flatt M(*) M(*) M(*) M(*) M(*) * * * * *
  • 40. Implementation of flatten flatten M(M(*)) M(*) flat_map id M(*) *
  • 41. Implementation of flatten flatten sub flatten { M(M(*)) M(*) my $m = shift; flat_map $m => &id; flat_map } id M(*) *
  • 42. flatten() has an important role on monads.
  • 43. Reduction of terms 6 3 2 8 + 9 2 8 + 11 8 + 19
  • 44. flatten() plays the same role M (M (M (M (*)))) flatten M (M (M (*))) flatten M (M (*)) flatten M (*)
  • 45. Can you illustrate another example of monads?
  • 47. Sample code of AE my $cv = AE::cv; http_get "http://yapcasia.org/2011/", sub { my ($data, $hdr) = @_; $cv->send($hdr->{'content-length'}); }; print $cv->recv;
  • 48. Sample code of AE my $cv = AE::cv; http_get "http://yapcasia.org/2011/", sub { my ($data, $hdr) = @_; $cv->send($hdr->{'content-length'}); }; print $cv->recv;
  • 50. CondVar isn’t a normal value # !! Can’t write in this way !! sub some_callback { my $cv = shift; print $cv, “n”; }
  • 51. Retrieve the value from $cv sub some_callback { my $cv = shift; print $cv->recv, “n”; }
  • 52. Run it ! % perl ./my_great_app.pl EV: error in callback (ignoring): AnyEvent::CondVar: recursive blocking wait attempted at ./my_great_app.pl line 9836
  • 53. You must use cb(). sub some_callback { my $cv = shift; $cv->cb(sub { print $_[0]->recv, "n"; }); }
  • 54. Use cb() sub some_callback { my $cv = shift; $cv->cb(sub { my $cv = next_task1 $_[0]->recv; $cv->cb(sub { my $cv = next_task2 $_[0]->recv; ... }); }); }
  • 55. Use cb() sub some_callback { my $cv = shift; $cv->cb(sub { my $cv = next_task1 $_[0]->recv; $cv->cb(sub { my $cv = next_task2 $_[0]->recv; $cv->cb(sub { my $cv = next_task3 $_[0]->recv; $cv->cb(sub { my $cv = next_task4 $_[0]->recv; ... }); }); }); }); }
  • 56. $cv->cb(sub { my $cv = next_task2 $_[0]->recv; $cv->cb(sub { Use cb() my $cv = next_task3 $_[0]->recv; $cv->cb(sub { my $cv = next_task4 $_[0]->recv; $cv->cb(sub { my $cv = next_task5 $_[0]->recv; $cv->cb(sub { my $cv = next_task6 $_[0]->recv; $cv->cb(sub { my $cv = next_task7 $_[0]->recv; $cv->cb(sub { my $cv = next_task8 $_[0]->recv; $cv->cb(sub { my $cv = next_task9 $_[0]->recv; $cv->cb(sub { my $cv = next_task10 $_[0]->recv; ... }); }); }); }); }); });
  • 58. Coro solves the problem
  • 59. Use Coro::AnyEvent sub some_callback { my $cv = shift; async { my $cv1 = next_task1($cv->recv); my $cv2 = next_task2($cv1->recv); my $cv3 = next_task3($cv2->recv); my $cv4 = next_task4($cv3->recv); ... }; }
  • 61. Though, Coro does some deep magic
  • 62. Organize the chaos by the monad pattern
  • 63. Let’s define a type and unit and flat_map
  • 64. AE::CondVar is the type # CondVar(STR) my $cv = AE::cv; $cv->send(‘Normal value’); # CondVar(CondVar(Str)) my $cvcv = AE::cv; $cvcv->send($cv); # CondVar(CondVar(CondVar(Str))) my $cvcvcv = AE::cv; $cvcvcv->send($cvcv);
  • 65. Which CondVar objs do normal values correspond to?
  • 66. We can retrieve a normal value without delay sub unit { my @values = @_ my $cv = AE::cv; $cv->send(@values); return $cv; }
  • 67. Think about flat_map() “foo” “Hi, $_[0]” after 3 sec after 2 sec flat_map say_hi $_[0] *
  • 68. Think about flat_map() $name->flat_map(&say_hi) 5 sec “Hi, foo” say_hi 2 sec “Hi, foo” $name 3 sec “foo”
  • 69. Implementation of flat_map sub flat_map { my ($cv, $f) = @_; $cv->cb(sub { my @values = $_[0]->recv; my $cv = $f->(@values); ... }) return ... }
  • 70. Implementation of flat_map sub flat_map { my ($cv, $f) = @_; my $result = AE::cv; $cv->cb(sub { my @values = $_[0]->recv; my $cv = $f->(@values); $cv->cb(sub { $result->send($_[0]->recv) }); }); return $result; }
  • 71. A monad comes with map and flatten
  • 72. Use the CondVar monad $cv ∋ CV(*) CV(*) CV(*) flat_map flat_map next_task1 next_task2 * * *
  • 73. Use the CondVar monad $cv sub some_callback { ∋ my $cv = shift; CV(*) CV(*) CV(*) $cv->flat_map(&next_task1) flat_map flat_map ->flat_map(&next_task2) ->flat_map(&next_task3) ->flat_map(&next_task4) ->... } next_task1 next_task2 * * *
  • 74. The CV monad has the continuation monad structure newtype Cont r a = Cont { runCont :: (a -> r) -> r } runCont cv $ v -> print v $cv->cb(sub { my @v = $_[0]->recv; print @v; });
  • 75. The CV monad also has the Either monad structure data Either String a = Left String | Right a (my $right = AE::cv)->send(“A right value”); (my $left = AE::cv)->croak(“A left value”);
  • 76. Handle exceptions in flat_map Left l >>= _ = Left l Right r >>= f = f r ... my $result = AE::cv; $cv->cb(sub { my @r = eval { $_[0]->recv }; return $result->croak($@) if $@; my $cv = $f->(@r); ... }); ...
  • 77. Define subs to handle errors sub fail { my @values = @_ my $cv = AE::cv; $cv->croak(@values); return $cv; }
  • 78. Define subs to handle errors sub catch { ... my $result = AE::cv; $cv->cb(sub { my @r = eval { $_[0]->recv }; return $result->send(@r) if @r; my $cv = $f->($@); ... }); ...
  • 79. A sample code of catch unit(1, 0)->flat_map(sub { my @v = eval { $_[0] / $_[1] }; $@ ? fail($@) : unit(@v); })->catch(sub { my $exception = shift; $exception =~ /Illegal division/ ? unit(0) # recover from errors : fail($exception); # rethrow })->flat_map(sub { ... });
  • 80. Does everything go well?
  • 81. NO
  • 83. Concurrency sequence CV(*), CV(*) CV(*, *)
  • 84. There’re no alchemy. Oo CV(*, *) ps! CV(*, *) map id *, * *, *
  • 85. Define it directly sub sequence { my ($cv1, $cv2) = @_; $cv1->flat_map(sub { my @v1 = @_; $cv2->flat_map(sub { my @v2 = @_; unit(@v1, @v2); }); }); }
  • 86. Use nested blocks to handle more than one monad $cv1->flat_map(sub { my @v1 = @_; $cv2->flat_map(sub { my @v2 = @_; $cv3->flat_map(sub { my @v3 = @_; $cv4->flat_map(sub { my @v4 = @_; $cv5->flat_map(sub { my @v5 = @_; ...
  • 87. Back to the hell
  • 88. Haskell’s do expression do v1 <- cv1 v2 <- cv2 v3 <- cv3 v4 <- cv4 ... return (v1, v2, v3, v4, ...)
  • 89. The for comprehension Data::Monad::Base::Sugar::for { pick my @v1 => sub { $cv1 }; pick my @v2 => sub { $cv2 }; pick my @v3 => sub { $cv3 }; pick my @v4 => sub { $cv4 }; ... yield { @v1, @v2, @v3, @v4, ... }; };
  • 90. ex). Better implementation of sequence sub sequence { my ($cv1, $cv2) = @_; $cv1->flat_map(sub { my @v1 = @_; $cv2->flat_map(sub { my @v2 = @_; unit(@v1, @v2); }); }); }
  • 91. ex). Better implementation of sequence sub sequence { my ($cv1, $cv2) = @_; Data::Monad::Base::Sugar::for { pick my @v1 => sub { $cv1 }; pick my @v2 => sub { $cv2 }; yield { @v1, @v2 }; }; }
  • 92. Conclusion A monad is made of a type, flat_map, unit Consider AE::cv as a monad CondVar monads save you from a callback hell https://github.com/hiratara/p5-Data-Monad