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

Objective-C for Java developers
Objective-C for Java developersObjective-C for Java developers
Objective-C for Java developersFábio Bernardo
 
119 Powerpoint 2.6
119 Powerpoint 2.6119 Powerpoint 2.6
119 Powerpoint 2.6Jeneva Clark
 
Google collections api an introduction
Google collections api   an introductionGoogle collections api   an introduction
Google collections api an introductiongosain20
 
2015 02-18 xxx-literalconvertible
2015 02-18 xxx-literalconvertible2015 02-18 xxx-literalconvertible
2015 02-18 xxx-literalconvertibleTaketo Sano
 
C - aptitude3
C - aptitude3C - aptitude3
C - aptitude3Srikanth
 
Python Cheat Sheet
Python Cheat SheetPython Cheat Sheet
Python Cheat SheetGlowTouch
 
밑바닥부터 시작하는 의료 AI
밑바닥부터 시작하는 의료 AI밑바닥부터 시작하는 의료 AI
밑바닥부터 시작하는 의료 AINAVER Engineering
 
Composicion de funciones
Composicion de funcionesComposicion de funciones
Composicion de funcionesPaito Sarauz
 
5.1 analysis of function i
5.1 analysis of function i5.1 analysis of function i
5.1 analysis of function idicosmo178
 
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 212Mahmoud Samir Fayed
 
Monads from Definition
Monads from DefinitionMonads from Definition
Monads from DefinitionDierk König
 
รายงานคอม
รายงานคอมรายงานคอม
รายงานคอมAreeya Onnom
 
รายงานคอม
รายงานคอมรายงานคอม
รายงานคอมAreeya Onnom
 
Funct format sql_statement.c
Funct format sql_statement.cFunct format sql_statement.c
Funct format sql_statement.calbertinous
 

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

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)Eric Torreborre
 
The Essence of the Iterator Pattern
The Essence of the Iterator PatternThe Essence of the Iterator Pattern
The Essence of the Iterator PatternEric Torreborre
 
Monad Transformers In The Wild
Monad Transformers In The WildMonad Transformers In The Wild
Monad Transformers In The WildStackMob 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
 
Software Visualization 101+
Software Visualization 101+Software Visualization 101+
Software Visualization 101+Michele Lanza
 
#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 .docxgertrudebellgrove
 
Datamining r 4th
Datamining r 4thDatamining r 4th
Datamining r 4thsesejun
 
Modular Module Systems
Modular Module SystemsModular Module Systems
Modular Module Systemsleague
 
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 GoEleanor McHugh
 
Haskellで学ぶ関数型言語
Haskellで学ぶ関数型言語Haskellで学ぶ関数型言語
Haskellで学ぶ関数型言語ikdysfm
 
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)Nadeem Uddin
 
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2Functional Pe(a)rls version 2
Functional Pe(a)rls version 2osfameron
 
Fp in scala with adts
Fp in scala with adtsFp in scala with adts
Fp in scala with adtsHang Zhao
 
Software Visualization - Promises & Perils
Software Visualization - Promises & PerilsSoftware Visualization - Promises & Perils
Software Visualization - Promises & PerilsMichele Lanza
 
ML: A Strongly Typed Functional Language
ML: A Strongly Typed Functional LanguageML: A Strongly Typed Functional Language
ML: A Strongly Typed Functional Languagelijx127
 

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

レンズ (ぶつかり稽古の没プレゼン)
レンズ (ぶつかり稽古の没プレゼン)レンズ (ぶつかり稽古の没プレゼン)
レンズ (ぶつかり稽古の没プレゼン)Masahiro Honma
 
すべてが@__kanになる
すべてが@__kanになるすべてが@__kanになる
すべてが@__kanになるMasahiro Honma
 
Types and perl language
Types and perl languageTypes and perl language
Types and perl languageMasahiro Honma
 
カレーとHokkaidopm
カレーとHokkaidopmカレーとHokkaidopm
カレーとHokkaidopmMasahiro Honma
 
モナモナ言うモナド入門.tar.gz
モナモナ言うモナド入門.tar.gzモナモナ言うモナド入門.tar.gz
モナモナ言うモナド入門.tar.gzMasahiro Honma
 
モナモナ言うモナド入門
モナモナ言うモナド入門モナモナ言うモナド入門
モナモナ言うモナド入門Masahiro Honma
 
循環参照のはなし
循環参照のはなし循環参照のはなし
循環参照のはなしMasahiro Honma
 
Hachioji.pm in Machida の LT
Hachioji.pm in Machida の LTHachioji.pm in Machida の LT
Hachioji.pm in Machida の LTMasahiro Honma
 
ウヰスキーとPSGI
ウヰスキーとPSGIウヰスキーとPSGI
ウヰスキーとPSGIMasahiro Honma
 
モデルから知るGit
モデルから知るGitモデルから知るGit
モデルから知るGitMasahiro Honma
 
YAPCレポートの舞台裏
YAPCレポートの舞台裏YAPCレポートの舞台裏
YAPCレポートの舞台裏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

A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024Results
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...gurkirankumar98700
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slidevu2urc
 
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...Drew Madelung
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
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...Martijn de Jong
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Servicegiselly40
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Allon Mureinik
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024The Digital Insurer
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilV3cube
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...apidays
 
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 DevelopmentsTrustArc
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure servicePooja Nehwal
 

Recently uploaded (20)

A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
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...
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
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...
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of Brazil
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
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
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
 

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