Created
November 5, 2013 01:12
-
-
Save felipecrv/7312211 to your computer and use it in GitHub Desktop.
The Maybe Monad [1] in PHP inspired by Scala's implementation of this concept which they call Option [2]. [1] http://en.wikipedia.org/wiki/Monad_%28functional_programming%29#The_Maybe_monad
[2] http://www.scala-lang.org/api/current/scala/Option.html
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
interface Option/*[T]*/ { | |
/** | |
* @return T | |
*/ | |
public function get(); | |
/** | |
* @param => T $f | |
* @return T | |
*/ | |
public function getOrElseLazy($f); | |
/** | |
* @param mixed $alt | |
* @return Option[mixed] | |
*/ | |
public function orElse($alt); | |
/** | |
* @param T => U $f | |
* @return Option[U] | |
*/ | |
public function map($f); | |
/** | |
* @return T | |
*/ | |
public function orNull(); | |
/** | |
* @return bool | |
*/ | |
public function isDefined(); | |
/** | |
* @return bool | |
*/ | |
public function isEmpty(); | |
} | |
class None implements Option { | |
public function get() { | |
invariant_violation('Trying to get value from None'); | |
} | |
public function getOrElse($alt) { | |
return $alt; | |
} | |
public function getOrElseLazy($f) { | |
return $f(); | |
} | |
public function orElse($alt) { | |
return option($alt); | |
} | |
public function map($f) { | |
return none(); | |
} | |
public function orNull() { | |
return null; | |
} | |
public function isDefined() { | |
return false; | |
} | |
public function isEmpty() { | |
return true; | |
} | |
public function __toString() { | |
return null; | |
} | |
} | |
class Some { | |
private $v; | |
public function __construct($v) { | |
$this->v = $v; | |
} | |
public function get() { | |
return $this->v; | |
} | |
public function getOrElse($alt) { | |
return $this->v; | |
} | |
public function orElse($alt) { | |
return $this; | |
} | |
public function getOrElseLazy($f) { | |
return $this->v; | |
} | |
public function orNull() { | |
return $this->v; | |
} | |
public function map($f) { | |
return new Some($f($this->v)); | |
} | |
public function isDefined() { | |
return true; | |
} | |
public function isEmpty() { | |
return false; | |
} | |
public function __toString() { | |
return (string) $this->v; | |
} | |
} | |
function none() { | |
static $instance = null; | |
if (!$instance) { | |
$instance = new None(); | |
} | |
return $instance; | |
} | |
function some($v) { | |
return new Some($v); | |
} | |
function option($v) { | |
if ($v === null) { | |
return none(); | |
} | |
return new Some($v); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Awesome. Thank you!