Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Functional Structures in PHP

Back in the ’40s, Samuel Eilenberg and Saunders Mac Lane started developing an entire new branch of mathematics: Category Theory. This was 10 years after Lambda calculus and 10 years before Lisp. Mathematics offers a powerful and concise language; we can represent a lot of complexity with short equations like E=mc2.

This session will explore how programming can harness maths’ capacity for conciseness and expression, borrowing from Category Theory. We’ll discover algebraic data types that can impact the way we code tremendously. You’ll also learn about functors, monads, applicatives, semigroups and monoids and how they can be used in a PHP context.

Functional Structures in PHP

  1. 1. {unctionalStructures byMarcelloDuarte @_md f inPHP
  2. 2. @_md#phpbnl17 Expressinganything
  3. 3. @_md#phpbnl17
  4. 4. @_md#phpbnl17 categorytheory
  5. 5. @_md#phpbnl17 categorytheory somecoolstructures somearrows somelaws {
  6. 6. @_md#phpbnl17 A B
  7. 7. @_md#phpbnl17 A B "PHPBenelux" 10
  8. 8. @_md#phpbnl17 A B "PHPBenelux" 10
  9. 9. @_md#phpbnl17 A B "PHPBenelux" f 10
  10. 10. @_md#phpbnl17 B 10 C true
  11. 11. @_md#phpbnl17 B 10 C true
  12. 12. @_md#phpbnl17 B 10 C true g
  13. 13. @_md#phpbnl17
  14. 14. @_md#phpbnl17 github.com/phunkie/phunkie
  15. 15. @_md#phpbnl17 SEMIGROUPS @_md#phpbnl17 https://upload.wikimedia.org/wikipedia/commons/c/c2/Falkland_Islands_Penguins_40.jpg
  16. 16. @_md#phpbnl17 combine(1, 2) == 3; combine("a", "b") == "ab"; combine(true, false) == false;
  17. 17. @_md#phpbnl17 h
  18. 18. @_md#phpbnl17 $f = function(string $a): int { return strlen($a); };
  19. 19. @_md#phpbnl17 $f = function(string $a): int { return strlen($a); }; $g = function(int $b): bool { return $b % 2 === 0; };
  20. 20. @_md#phpbnl17 $f = function(string $a): int { return strlen($a); }; $g = function(int $b): bool { return $b % 2 === 0; }; $h = combine($f, g); $h("PHPBenelux") == true;
  21. 21. @_md#phpbnl17 combine($f, g) == compose ($f, $g) // if $f and $g are functions
  22. 22. @_md#phpbnl17 compose ("strlen", odd, Option, ...)
  23. 23. @_md#phpbnl17 laws
  24. 24. @_md#phpbnl17 combine(combine(1, 2), 3) == combine(1, combine(2, 3)) associativity
  25. 25. @_md#phpbnl17 MONOIDS @_md#phpbnl17 https://upload.wikimedia.org/wikipedia/commons/c/c2/Falkland_Islands_Penguins_40.jpg
  26. 26. @_md#phpbnl17 $identity = function ($x) { return $x; }; A "PHPBenelux" i
  27. 27. @_md#phpbnl17 zero(42) == 0; zero("any string") == ""; zero(true, false) == true;
  28. 28. @_md#phpbnl17 laws
  29. 29. @_md#phpbnl17 combine(combine(1, 2), 3) == combine(1, combine(2, 3)) combine(zero($x), $x) == $x combine($x, zero($x)) == $x associativity (left and right) identity
  30. 30. @_md#phpbnl17 interface Monoid extends Semigroup {
 public function zero(); // inherited from Semigroup public function combine($another); }
  31. 31. @_md#phpbnl17 interface Monoid extends Semigroup {
 public function zero(); // inherited from Semigroup public function combine($another); } class Balance implements Monoid { // ... }
  32. 32. @_md#phpbnl17 $deposit100bucks = function(Balance $b) { return $b->plus(100); }
 
 $listOfBalances->foldMap($deposit100bucks);
  33. 33. @_md#phpbnl17 FUNCTORS @_md#phpbnl17 https://upload.wikimedia.org/wikipedia/commons/3/3b/World_Map_1689.JPG
  34. 34. @_md#phpbnl17 kinds
  35. 35. @_md#phpbnl17 proper {
  36. 36. @_md#phpbnl17 givemeanumber
  37. 37. @_md#phpbnl17 42givemeanumber
  38. 38. @_md#phpbnl17 givemeaword
  39. 39. @_md#phpbnl17 givemeaword "cabuzle"
  40. 40. @_md#phpbnl17 proper first-order{
  41. 41. @_md#phpbnl17 givemealist
  42. 42. @_md#phpbnl17 givemealist …
  43. 43. @_md#phpbnl17 givemealist alistofwhat?
  44. 44. @_md#phpbnl17 ImmList(1,2,3) // List<Int>
 ImmList("a thing", "another thing") // List<String>

  45. 45. @_md#phpbnl17 ImmList(1,2,3) // List<Int>
 ImmList("a thing", "another thing") // List<String>
  46. 46. @_md#phpbnl17 abstract class Option {} class Some extends Option {} class None extends Option {}
  47. 47. @_md#phpbnl17 phunkie > Option(42) $var0: Option<Int> = Some(42) phunkie > Option(null) $var1: None = None 
 

  48. 48. @_md#phpbnl17 phunkie > $f = compose(mayBeRubish, Option)
 phunkie > $f(42) $var0: None = None 
 

  49. 49. @_md#phpbnl17 proper first-order higherorder {
  50. 50. @_md#phpbnl17 function fmap(Mappable $mappable, callable $f) { return $mappable->map($f); }
  51. 51. @_md#phpbnl17 $listOfWords = ImmList("guacamole", "nose", "penguin"); $lengths = fmap ("strlen") ($listOfWords); // List (9, 4, 7)
  52. 52. @_md#phpbnl17 $maybeSomeGuaca = Option("guacamole"); $length = fmap ("strlen") ($maybeSomeGuaca); // Some (9)
  53. 53. @_md#phpbnl17 $maybeSomeGuaca = Option("guacamole"); $length = fmap ("strlen") ($maybeSomeGuaca); // Some (9) $maybeSomeGuaca = Option(null); $length = fmap ("strlen") ($maybeSomeGuaca);
 
 // None
  54. 54. @_md#phpbnl17 // Already Mappable in Phunkie ImmList Option Function1 Validations (Either) // Planned ImmMap ImmSet Tuples (inc. Pair)
  55. 55. @_md#phpbnl17 laws
  56. 56. @_md#phpbnl17 $fa == fmap(identity)($fa) fmap(compose($f, $g))($fa) == fmap($g)(fmap($f)($fa)) covariant identity covariant composition
  57. 57. @_md#phpbnl17 APPLICATIVE @_md#phpbnl17 https://upload.wikimedia.org/wikipedia/commons/5/5c/Brick_and_block_laying.jpg
  58. 58. @_md#phpbnl17 interface Apply extends Functor
 { public function apply($ff);
 public function map2($fb, callable $f);
 } interface Applicative extends Apply
 {
 public function pure($a);
 }
  59. 59. @_md#phpbnl17 /** * @param A $a * @return FirstOrderKind<A> */ function pure($a)
  60. 60. @_md#phpbnl17 /** * @param A $a * @return FirstOrderKind<A> */ function pure($a) Option()->pure(42); // Some(42)
  61. 61. @_md#phpbnl17 /** * @param A $a * @return FirstOrderKind<A> */ function pure($a) Option()->pure(42); // Some(42) ImmList()->pure(42); // ImmList(42)
  62. 62. @_md#phpbnl17 /** * @param FirstOrderKind<callable<A,B>> $ff * @return FirstOrderKind<B> */ function apply($ff)
  63. 63. @_md#phpbnl17 /** * @param FirstOrderKind<callable<A,B>> $ff * @return FirstOrderKind<B> */ function apply($ff) $increment = function($x){ return $x + 1;}; 

  64. 64. @_md#phpbnl17 /** * @param FirstOrderKind<callable<A,B>> $ff * @return FirstOrderKind<B> */ function apply($ff) Some(1)->apply(Some($increment));
  65. 65. @_md#phpbnl17 /** * @param FirstOrderKind<callable<A,B>> $ff * @return FirstOrderKind<B> */ function apply($ff) Some(1)->apply(Some($increment)); // Some(2)

  66. 66. @_md#phpbnl17 /** * @param FirstOrderKind<callable<A,B>> $ff * @return FirstOrderKind<B> */ function apply($ff) Some(1)->apply(Some($increment)); // Some(2)
 None()->apply(Some($increment));

  67. 67. @_md#phpbnl17 /** * @param FirstOrderKind<callable<A,B>> $ff * @return FirstOrderKind<B> */ function apply($ff) Some(1)->apply(Some($increment)); // Some(2)
 None()->apply(Some($increment));
 // None
  68. 68. @_md#phpbnl17 /** * @param FirstOrderKind<callable<A,B>> $ff * @return FirstOrderKind<B> */ function apply($ff) Some(1)->apply(Some($increment)); // Some(2)
 None()->apply(Some($increment));
 // None ImmList(1,2,3)->apply(ImmList($increment));

  69. 69. @_md#phpbnl17 /** * @param FirstOrderKind<callable<A,B>> $ff * @return FirstOrderKind<B> */ function apply($ff) Some(1)->apply(Some($increment)); // Some(2)
 None()->apply(Some($increment));
 // None ImmList(1,2,3)->apply(ImmList($increment));
 // ImmList(2,3,4)
  70. 70. @_md#phpbnl17 /** * @param FirstOrderKind<B> $fb * @param (A, B) => C $ * @return FirstOrderKind<C> */ function map2($fb, callable $f)
  71. 71. @_md#phpbnl17 /** * @param FirstOrderKind<B> $fb * @param (A, B) => C $ * @return FirstOrderKind<C> */ function map2($fb, callable $f) Some(1)->map2(Some(2), function($x, $y) { return $x + $y; });;
  72. 72. @_md#phpbnl17 /** * @param FirstOrderKind<B> $fb * @param (A, B) => C $ * @return FirstOrderKind<C> */ function map2($fb, callable $f) Some(1)->map2(Some(2), function($x, $y) { return $x + $y; });;
  73. 73. @_md#phpbnl17 /** * @param FirstOrderKind<B> $fb * @param (A, B) => C $ * @return FirstOrderKind<C> */ function map2($fb, callable $f) Some(1)->map2(Some(2), function($x, $y) { return $x + $y; });; // Some(3)

  74. 74. @_md#phpbnl17 /** * @param FirstOrderKind<B> $fb * @param (A, B) => C $ * @return FirstOrderKind<C> */ function map2($fb, callable $f) Some(1)->map2(Some(2), function($x, $y) { return $x + $y; });; // Some(3)
 ImmList(1,2)->map2(ImmList(4,5), function($x, $y) { return $x + $y; });

  75. 75. @_md#phpbnl17 /** * @param FirstOrderKind<B> $fb * @param (A, B) => C $ * @return FirstOrderKind<C> */ function map2($fb, callable $f) Some(1)->map2(Some(2), function($x, $y) { return $x + $y; });; // Some(3)
 ImmList(1,2)->map2(ImmList(4,5), function($x, $y) { return $x + $y; });
 // ImmList(5,6,6,7)
  76. 76. @_md#phpbnl17 laws
  77. 77. @_md#phpbnl17 $fa->apply($fa->pure(identity)) == $fa $fa->pure($a)->fa->apply($fa->pure($f)) ==
 $fa->pure($f($a)) identity homomorphism
  78. 78. @_md#phpbnl17 $fa->pure($a)->apply ==
 $fab->apply($fa->pure(function($f)use($a){return $f($a)})) $fa->map($f) == $fa->apply($fa->pure($f)) interchange map
  79. 79. @_md#phpbnl17 whywouldyoueveruseafunctor?
  80. 80. @_md#phpbnl17 weakertypesaremorepredictable
  81. 81. @_md#phpbnl17 $xs = fmap (ImmList(1,2,3)) ($f); echo $xs->length;
  82. 82. @_md#phpbnl17 MONADS @_md#phpbnl17 https://upload.wikimedia.org/wikipedia/commons/b/bd/Golden_tabby_and_white_kitten_n01.jpg
  83. 83. @_md#phpbnl17 interface FlatMap extends Functor
 { public function flatMap(callable $f);
 } interface Monad extends FlatMap
 {
 public function flatten();
 }
  84. 84. @_md#phpbnl17 /** * @param (A) -> FirstOrderKind<B> $a * @return FirstOrderKind<B> */ function flatMap($a)
  85. 85. @_md#phpbnl17 /** * @param (A) -> FirstOrderKind<B> $a * @return FirstOrderKind<B> */ function flatMap($a) Option(42)->flatMap(function($x) { return Some($x + 1); });
  86. 86. @_md#phpbnl17 /** * @param (A) -> FirstOrderKind<B> $a * @return FirstOrderKind<B> */ function flatMap($a) Option(42)->flatMap(function($x) { return Some($x + 1); });
  87. 87. @_md#phpbnl17 /** * @param (A) -> FirstOrderKind<B> $a * @return FirstOrderKind<B> */ function flatMap($a) Option(42)->flatMap(function($x) { return Some($x + 1); });
  88. 88. @_md#phpbnl17 /** * @param (A) -> FirstOrderKind<B> $a * @return FirstOrderKind<B> */ function flatMap($a) Option(42)->flatMap(function($x) { return Some($x + 1); }); // Some(43)
  89. 89. @_md#phpbnl17 /** * @param (A) -> FirstOrderKind<B> $a * @return FirstOrderKind<B> */ function flatMap($a) Option(42)->flatMap(function($x) { return Some($x + 1); }); // Some(43) ImmList(1,2,3)->flatMap(function($x) { return Option($x % 2 === 0 ? null : $x); }); // ImmList(1,3)
  90. 90. @_md#phpbnl17 /** * @return FirstOrderKind<B> */ function flatten() Some(Some(42))->flatten(); // Some(42)
  91. 91. @_md#phpbnl17 /** * @param (A) -> FirstOrderKind<B> $a * @return FirstOrderKind<B> */ function flatMap($a) Option(42)->flatMap(function($x) { return Some($x + 1); }); // Some(43) ImmList(1,2,3)->flatMap(function($x) { return Option($x % 2 === 0 ? null : $x); }); // ImmList(1,3)
  92. 92. @_md#phpbnl17 laws
  93. 93. @_md#phpbnl17 $fa->flatMap($f)->flatMap($g) == $fa->flatMap(function($a) use ($f,$g) { return $f($a)->flatMap( function($b) use ($g) { return $g($b); } ) ;}) $fa->pure($a)->flatMap($f) == $f($a) associativity right and left identity $fa->flatMap(function($a) use ($fa) { return $fa- >pure($a); }) == $fa;
  94. 94. @_md#phpbnl17 monadsyntaxsugar
  95. 95. @_md#phpbnl17 function repl($state)
 {
 return read()->
 flatMap(evaluate)->
 flatMap(andPrint)->
 flatMap(loop)
 ->run($state);
 } def repl(state) =
 for { (s,input) <- read
 (s,result)<- evaluate
 s <- andPrint
 s <- loop
 } yield s

  96. 96. @_md#phpbnl17 monadcomposability
  97. 97. @_md#phpbnl17 f(A $a): M<B>
 
 g(B $b): M<C>
  98. 98. f(a) ~= M<B>
 f(a) map g ~= M<M<C>> 

  99. 99. f(a) ~= M<B>
 f(a) map g ~= M<M<C>> 
 urgh!
  100. 100. @_md#phpbnl17 butyoucancomposethemonad’sfunctions!
  101. 101. 
 flatten f(a) map g ~= M<C> 

  102. 102. @_md#phpbnl17 VALIDATIONS @_md#phpbnl17 http://www.sbs.com.au/topics/sites/sbs.com.au.topics/files/gettyimages-470309868.jpg
  103. 103. @_md#phpbnl17 abstract class Validation {} class Success extends Validation {} class Failure extends Validation {}
  104. 104. @_md#phpbnl17 phunkie > Success(42) $var0: Validation<E, Int> = Success(42) phunkie > Failure("nay") $var0: Validation<String, A> = Failure("nay") 
 

  105. 105. @_md#phpbnl17 phunkie > Either("nay")(42) $var0: Validation<E, Int> = Success(42) phunkie > Either("nay")(null) $var0: Validation<String, A> = Failure("nay") 
 

  106. 106. @_md#phpbnl17 marcelloduarte @PhunkiePhp {
  107. 107. @_md#phpbnl17 thanks {bit.ly/inviqa-contact bit.ly/inviqa-careers you!
  108. 108. @_md#phpbnl17 credits https://upload.wikimedia.org/wikipedia/commons/c/c2/Falkland_Islands_Penguins_40.jpg {https://upload.wikimedia.org/wikipedia/commons/3/3b/World_Map_1689.JPG https://upload.wikimedia.org/wikipedia/commons/5/5c/Brick_and_block_laying.jpg https://upload.wikimedia.org/wikipedia/commons/b/bd/Golden_tabby_and_white_kitten_n01.jpg
  109. 109. @_md#phpbnl17 Questions? 
 joind.in/talk/75f65 ?

    Be the first to comment

    Login to see the comments

  • 9gagiu

    Jan. 27, 2017
  • nikolaizujev

    Jan. 29, 2017
  • denisristic1

    Jun. 1, 2017
  • tofunmi

    Jun. 14, 2018

Back in the ’40s, Samuel Eilenberg and Saunders Mac Lane started developing an entire new branch of mathematics: Category Theory. This was 10 years after Lambda calculus and 10 years before Lisp. Mathematics offers a powerful and concise language; we can represent a lot of complexity with short equations like E=mc2. This session will explore how programming can harness maths’ capacity for conciseness and expression, borrowing from Category Theory. We’ll discover algebraic data types that can impact the way we code tremendously. You’ll also learn about functors, monads, applicatives, semigroups and monoids and how they can be used in a PHP context.

Views

Total views

13,945

On Slideshare

0

From embeds

0

Number of embeds

94

Actions

Downloads

17

Shares

0

Comments

0

Likes

4

×