{unctionalStructures byMarcelloDuarte @_md f inPHP
@_md#phpbnl17 Expressinganything
@_md#phpbnl17
@_md#phpbnl17 categorytheory
@_md#phpbnl17 categorytheory somecoolstructures somearrows somelaws {
@_md#phpbnl17 A B
@_md#phpbnl17 A B "PHPBenelux" 10
@_md#phpbnl17 A B "PHPBenelux" 10
@_md#phpbnl17 A B "PHPBenelux" f 10
@_md#phpbnl17 B 10 C true
@_md#phpbnl17 B 10 C true
@_md#phpbnl17 B 10 C true g
@_md#phpbnl17
@_md#phpbnl17 github.com/phunkie/phunkie
@_md#phpbnl17 SEMIGROUPS @_md#phpbnl17 https://upload.wikimedia.org/wikipedia/commons/c/c2/Falkland_Islands_Penguins_40.jpg
@_md#phpbnl17 combine(1, 2) == 3; combine("a", "b") == "ab"; combine(true, false) == false;
@_md#phpbnl17 h
@_md#phpbnl17 $f = function(string $a): int { return strlen($a); };
@_md#phpbnl17 $f = function(string $a): int { return strlen($a); }; $g = function(int $b): bool { return $b % 2 === 0; };
@_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;
@_md#phpbnl17 combine($f, g) == compose ($f, $g) // if $f and $g are functions
@_md#phpbnl17 compose ("strlen", odd, Option, ...)
@_md#phpbnl17 laws
@_md#phpbnl17 combine(combine(1, 2), 3) == combine(1, combine(2, 3)) associativity
@_md#phpbnl17 MONOIDS @_md#phpbnl17 https://upload.wikimedia.org/wikipedia/commons/c/c2/Falkland_Islands_Penguins_40.jpg
@_md#phpbnl17 $identity = function ($x) { return $x; }; A "PHPBenelux" i
@_md#phpbnl17 zero(42) == 0; zero("any string") == ""; zero(true, false) == true;
@_md#phpbnl17 laws
@_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
@_md#phpbnl17 interface Monoid extends Semigroup {
 public function zero(); // inherited from Semigroup public function combine($another); }
@_md#phpbnl17 interface Monoid extends Semigroup {
 public function zero(); // inherited from Semigroup public function combine($another); } class Balance implements Monoid { // ... }
@_md#phpbnl17 $deposit100bucks = function(Balance $b) { return $b->plus(100); }
 
 $listOfBalances->foldMap($deposit100bucks);
@_md#phpbnl17 FUNCTORS @_md#phpbnl17 https://upload.wikimedia.org/wikipedia/commons/3/3b/World_Map_1689.JPG
@_md#phpbnl17 kinds
@_md#phpbnl17 proper {
@_md#phpbnl17 givemeanumber
@_md#phpbnl17 42givemeanumber
@_md#phpbnl17 givemeaword
@_md#phpbnl17 givemeaword "cabuzle"
@_md#phpbnl17 proper first-order{
@_md#phpbnl17 givemealist
@_md#phpbnl17 givemealist …
@_md#phpbnl17 givemealist alistofwhat?
@_md#phpbnl17 ImmList(1,2,3) // List<Int>
 ImmList("a thing", "another thing") // List<String>

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

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

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

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

@_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));

@_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
@_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));

@_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)
@_md#phpbnl17 /** * @param FirstOrderKind<B> $fb * @param (A, B) => C $ * @return FirstOrderKind<C> */ function map2($fb, callable $f)
@_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; });;
@_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; });;
@_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)

@_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; });

@_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)
@_md#phpbnl17 laws
@_md#phpbnl17 $fa->apply($fa->pure(identity)) == $fa $fa->pure($a)->fa->apply($fa->pure($f)) ==
 $fa->pure($f($a)) identity homomorphism
@_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
@_md#phpbnl17 whywouldyoueveruseafunctor?
@_md#phpbnl17 weakertypesaremorepredictable
@_md#phpbnl17 $xs = fmap (ImmList(1,2,3)) ($f); echo $xs->length;
@_md#phpbnl17 MONADS @_md#phpbnl17 https://upload.wikimedia.org/wikipedia/commons/b/bd/Golden_tabby_and_white_kitten_n01.jpg
@_md#phpbnl17 interface FlatMap extends Functor
 { public function flatMap(callable $f);
 } interface Monad extends FlatMap
 {
 public function flatten();
 }
@_md#phpbnl17 /** * @param (A) -> FirstOrderKind<B> $a * @return FirstOrderKind<B> */ function flatMap($a)
@_md#phpbnl17 /** * @param (A) -> FirstOrderKind<B> $a * @return FirstOrderKind<B> */ function flatMap($a) Option(42)->flatMap(function($x) { return Some($x + 1); });
@_md#phpbnl17 /** * @param (A) -> FirstOrderKind<B> $a * @return FirstOrderKind<B> */ function flatMap($a) Option(42)->flatMap(function($x) { return Some($x + 1); });
@_md#phpbnl17 /** * @param (A) -> FirstOrderKind<B> $a * @return FirstOrderKind<B> */ function flatMap($a) Option(42)->flatMap(function($x) { return Some($x + 1); });
@_md#phpbnl17 /** * @param (A) -> FirstOrderKind<B> $a * @return FirstOrderKind<B> */ function flatMap($a) Option(42)->flatMap(function($x) { return Some($x + 1); }); // Some(43)
@_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)
@_md#phpbnl17 /** * @return FirstOrderKind<B> */ function flatten() Some(Some(42))->flatten(); // Some(42)
@_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)
@_md#phpbnl17 laws
@_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;
@_md#phpbnl17 monadsyntaxsugar
@_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

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

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

 flatten f(a) map g ~= M<C> 

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

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

@_md#phpbnl17 marcelloduarte @PhunkiePhp {
@_md#phpbnl17 thanks {bit.ly/inviqa-contact bit.ly/inviqa-careers you!
@_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
@_md#phpbnl17 Questions? 
 joind.in/talk/75f65 ?

Functional Structures in PHP