├── .editorconfig ├── .gitignore ├── .scrutinizer.yml ├── .travis.yml ├── LICENSE ├── README.md ├── build.xml ├── composer.json ├── examples ├── find.php └── welcome.php ├── phpunit.xml.dist ├── src ├── Just.php ├── JustInterface.php ├── Maybe.php ├── MaybeInterface.php ├── Nothing.php └── NothingInterface.php └── tests └── MaybeTest.php /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig is awesome: http://EditorConfig.org 2 | 3 | # top-most EditorConfig file 4 | root = true 5 | 6 | # Unix-style newlines with a newline ending every file 7 | [*] 8 | end_of_line = lf 9 | charset = utf-8 10 | indent_style = space 11 | insert_final_newline = true 12 | indent_size = 4 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /vendor/ 2 | composer.lock 3 | .idea/ 4 | build/ 5 | composer.lock 6 | -------------------------------------------------------------------------------- /.scrutinizer.yml: -------------------------------------------------------------------------------- 1 | build: 2 | environment: 3 | mysql: false 4 | postgresql: false 5 | redis: false 6 | rabbitmq: false 7 | php: 8 | version: 5.5 9 | 10 | tests: 11 | override: 12 | - 13 | command: 'phpunit --coverage-clover=logs/clover.xml' 14 | coverage: 15 | file: 'logs/clover.xml' 16 | format: 'php-clover' 17 | 18 | checks: 19 | php: 20 | code_rating: true 21 | duplication: true 22 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: php 2 | 3 | php: 4 | - 5.4 5 | - 5.5 6 | - 5.6 7 | - 7.0 8 | - hhvm 9 | 10 | matrix: 11 | allow_failures: 12 | - php: hhvm 13 | 14 | before_script: 15 | - composer self-update 16 | - composer install --prefer-dist 17 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Marcelo Camargo 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## PHP Maybe Monad 2 | 3 | 4 | [![Build Status](https://travis-ci.org/haskellcamargo/php-maybe-monad.svg?branch=master)](https://travis-ci.org/haskellcamargo/php-maybe-monad) [![Latest Stable Version](https://poser.pugx.org/haskellcamargo/php-maybe-monad/v/stable)](https://packagist.org/packages/haskellcamargo/php-maybe-monad) [![Total Downloads](https://poser.pugx.org/haskellcamargo/php-maybe-monad/downloads)](https://packagist.org/packages/haskellcamargo/php-maybe-monad) [![Latest Unstable Version](https://poser.pugx.org/haskellcamargo/php-maybe-monad/v/unstable)](https://packagist.org/packages/haskellcamargo/php-maybe-monad) [![License](https://poser.pugx.org/haskellcamargo/php-maybe-monad/license)](https://packagist.org/packages/haskellcamargo/php-maybe-monad) 5 | 6 | To deal with computations that may fail. 7 | A port of Haskell's `Data.Maybe` module for **PHP > 5.4**. 8 | 9 | ### Install 10 | You can install via Composer. 11 | 12 | ```bash 13 | composer require haskellcamargo/php-maybe-monad 14 | ``` 15 | 16 | ### Example 17 | 18 | ```php 19 | use HaskellCamargo\Maybe; 20 | 21 | Maybe\Maybe(@$_GET["username"])->bind(function($user)) { 22 | echo "Welcome, $user. You're logged in!"; 23 | }); 24 | 25 | $userAge = Maybe\Maybe(null)->fromMaybe(0); // => 0 26 | $userAge = Maybe\Maybe(19)->fromMaybe(0); // => 19 27 | ``` 28 | 29 | ### Documentation 30 | 31 | A `Maybe` type encapsulates an optional value. A value of type `Maybe a` 32 | either contains a value of type a (represented as `Just a`), or it is empty 33 | (represented as `Nothing`). Using `Maybe` is a good way to deal with errors 34 | or exceptional cases without resorting to drastic measures such as 35 | `Exception`. 36 | The `Maybe` type is also a monad. It is a simple kind of error monad, where 37 | all errors are represented by `Nothing`. A richer error monad can be built 38 | using the `Either` type. 39 | 40 | #### bind :: (Maybe a, callable) -> Maybe b 41 | 42 | Equivalent to Haskell's `>>=` operator. Its first argument is a value in 43 | a monadic type, its second argument is a function that maps from the 44 | underlying type of the first argument to another monadic type, and its 45 | results is in that other monadic type. 46 | 47 | ```php 48 | $age = Maybe\Maybe(null)->bind(function($x) { 49 | return 10; 50 | }); // => Nothing 51 | 52 | $age = Maybe\Maybe(10) 53 | ->bind(function($x) { 54 | return $x + 10; // => Just(20); 55 | }) 56 | ->bind(function($x) { 57 | return $x + 20; // => Just(40); 58 | })->fromJust(); // => 40 59 | ``` 60 | 61 | #### fromJust :: Maybe a -> a 62 | 63 | Extracts the element out of a `Just` and returns an error if its argument 64 | is `Nothing`. 65 | 66 | ```php 67 | Maybe\Maybe("Foo")->fromJust(); // => "Foo" 68 | Maybe\Maybe(null)->fromJust(); // => Exception: Cannot cal fromJust() on Nothing 69 | ``` 70 | 71 | #### fromMaybe :: (Maybe a, a) -> a 72 | 73 | Takes a `Maybe` value and a default value. If the `Maybe` is `Nothing`, it 74 | returns the default values; otherwise, it returns the value contained in 75 | the `Maybe`. 76 | 77 | ```php 78 | Maybe\Maybe(10)->fromMaybe(5); // => 10 79 | Maybe\Maybe(null)->fromMaybe(5); // => 5 80 | ``` 81 | 82 | #### isJust :: Maybe a -> boolean 83 | 84 | Returns true if its argument is of the form `Just _`. 85 | 86 | ```php 87 | Maybe\Maybe(10)->isJust(); // => true 88 | Maybe\Maybe(null)->isJust(); // => false 89 | ``` 90 | 91 | #### isNothing :: Maybe a -> boolean 92 | 93 | Returns true if its argument is of the form `Nothing`. 94 | 95 | ```php 96 | Maybe\Maybe(10)->isNothing(); // => false 97 | Maybe\Maybe(null)->isNothing(); // => true 98 | ``` 99 | 100 | #### maybe :: (Maybe a, b, callable) -> b 101 | 102 | Takes a default value, a function and, of course, a `Maybe` value. If the 103 | `Maybe` value is `Nothing`, the function returns the default value. 104 | Otherwise, it applies the function to the value inside the `Just` and 105 | returns the result. 106 | 107 | ```php 108 | $just = Maybe\Maybe(10); 109 | $nothing = Maybe\Maybe(null); 110 | 111 | $just->maybe(40, function($num) { 112 | return $num + 15; 113 | }); // => 25 114 | 115 | $nothing->maybe(40, function($num) { 116 | return $num + 15; 117 | }); // => 40 118 | ``` 119 | 120 | #### toList :: Maybe a -> array 121 | 122 | Returns an empty list when given ``Nothing`` or a singleton list when not 123 | given ``Nothing``. 124 | 125 | ```php 126 | Maybe\Maybe(10)->toList(); // => [10] 127 | Maybe\Maybe(null)->toList(); // => [] 128 | ``` 129 | 130 | Made with :heart: by Marcelo Camargo and Reinaldo Rauch 131 | 132 | ### License 133 | MIT 134 | -------------------------------------------------------------------------------- /build.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "haskellcamargo/php-maybe-monad", 3 | "description": "A PHP implementation of Haskell's Maybe monad", 4 | "type": "library", 5 | "license": "MIT", 6 | "authors": [ 7 | { 8 | "name": "Marcelo Camargo", 9 | "email": "marcelocamargo@linuxmail.org" 10 | }, 11 | { 12 | "name": "Reinaldo A. C. Rauch", 13 | "email": "reinaldorauch@gmail.com" 14 | } 15 | ], 16 | "minimum-stability": "stable", 17 | "require": { 18 | "php": "^5.4|^7.0" 19 | }, 20 | "require-dev": { 21 | "phpunit/phpunit": "^4.7", 22 | "pdepend/pdepend": "~2.0", 23 | "phing/phing": "~2.10", 24 | "phploc/phploc": "~2.1", 25 | "phpmd/phpmd": "~2.2", 26 | "sebastian/phpcpd": "~2.0", 27 | "squizlabs/php_codesniffer": "~2.1" 28 | }, 29 | "autoload": { 30 | "psr-4": { 31 | "HaskellCamargo\\Maybe\\": "src" 32 | }, 33 | "files": [ 34 | "src/Maybe.php" 35 | ] 36 | }, 37 | "autoload-dev": { 38 | "psr-4": { 39 | "HaskellCamargo\\Maybe\\Tests\\": "tests" 40 | } 41 | }, 42 | "scripts": { 43 | "test": "vendor/bin/phpunit tests/" 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /examples/find.php: -------------------------------------------------------------------------------- 1 | xs = $xs; 22 | } 23 | 24 | public function find($entity, $name) 25 | { 26 | $xss = array_filter($this->xs, function ($x) use ($name) { 27 | return $x === $name; 28 | }); 29 | 30 | $x = head($xss); 31 | 32 | if ($x) { 33 | return new $entity($x); 34 | } 35 | 36 | return null; 37 | } 38 | 39 | } 40 | 41 | 42 | // your codebase 43 | class User 44 | { 45 | private $name; 46 | 47 | public function __construct($name) 48 | { 49 | $this->name = $name; 50 | } 51 | 52 | public function getName() 53 | { 54 | return $this->name; 55 | } 56 | } 57 | 58 | class UserRepository 59 | { 60 | public function __construct(ArrayMemory $em) 61 | { 62 | $this->em = $em; 63 | } 64 | 65 | public function findByName($name, User $def = null) 66 | { 67 | $user = $this->em->find(User::class, $name); 68 | 69 | return Maybe\Maybe($user)->fromMaybe($def ?: new User('None')); 70 | } 71 | } 72 | 73 | $users = ['Hetfield', 'Hendrix']; 74 | $store = new ArrayMemory($users); 75 | $repo = new UserRepository($store); 76 | 77 | $hendrix = $repo->findByName('Hendrix'); 78 | $none = $repo->findByName('Fake', new User('Fred')); 79 | 80 | assert($hendrix instanceof User); 81 | assert($hendrix->getName() === 'Hendrix'); 82 | 83 | assert($none instanceof User); 84 | assert($none->getName() === 'Fred'); 85 | -------------------------------------------------------------------------------- /examples/welcome.php: -------------------------------------------------------------------------------- 1 | name = $name; 14 | } 15 | 16 | public function getName() 17 | { 18 | return $this->name; 19 | } 20 | } 21 | 22 | class Welcome 23 | { 24 | private $name; 25 | 26 | public function __construct($name) 27 | { 28 | $this->name = $name ?: null; 29 | } 30 | 31 | public function hello($def = 'Unknown') 32 | { 33 | $user = new User( 34 | Maybe\Maybe($this->name)->fromMaybe($def) 35 | ); 36 | 37 | return sprintf('Hello, %s', $user->getName()); 38 | } 39 | } 40 | 41 | echo 'Type your name: '; 42 | $name = trim(fgets(STDIN)); 43 | 44 | echo (new Welcome($name))->hello(); 45 | -------------------------------------------------------------------------------- /phpunit.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 19 | 20 | 21 | tests/ 22 | 23 | 24 | 25 | 26 | 27 | src/ 28 | 29 | vendor/ 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /src/Just.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Permission is hereby granted, free of charge, to any person 7 | * obtaining a copy of this software and associated documentation files 8 | * (the "Software"), to deal in the Software without restriction, 9 | * including without limitation the rights to use, copy, modify, merge, 10 | * publish, distribute, sublicense, and/or sell copies of the Software, 11 | * and to permit persons to whom the Software is furnished to do so, 12 | * subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be 15 | * included in all copies or substantial of portions the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 21 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 23 | * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | namespace HaskellCamargo\Maybe; 27 | 28 | /** 29 | * `Just` is a constructor of the `Maybe` type/monad. It must carry a value. 30 | */ 31 | class Just implements MaybeInterface, JustInterface 32 | { 33 | /** 34 | * @var mixed 35 | */ 36 | private $value; 37 | 38 | /** 39 | * @param mixed $value 40 | */ 41 | public function __construct($value) 42 | { 43 | $this->value = $value; 44 | } 45 | 46 | /** 47 | * {@inheritdoc} 48 | */ 49 | public function bind(callable $fn) 50 | { 51 | return Maybe($fn($this->value)); 52 | } 53 | 54 | /** 55 | * {@inheritdoc} 56 | */ 57 | public function fromJust() 58 | { 59 | return $this->value; 60 | } 61 | 62 | /** 63 | * {@inheritdoc} 64 | */ 65 | public function fromMaybe($_) 66 | { 67 | return $this->value; 68 | } 69 | 70 | /** 71 | * {@inheritdoc} 72 | */ 73 | public function isJust() 74 | { 75 | return true; 76 | } 77 | 78 | /** 79 | * {@inheritdoc} 80 | */ 81 | public function isNothing() 82 | { 83 | return false; 84 | } 85 | 86 | /** 87 | * {@inheritdoc} 88 | */ 89 | public function maybe($_, callable $fn) 90 | { 91 | return $fn($this->value); 92 | } 93 | 94 | /** 95 | * {@inheritdoc} 96 | */ 97 | public function toList() 98 | { 99 | return [$this->value]; 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /src/JustInterface.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Permission is hereby granted, free of charge, to any person 7 | * obtaining a copy of this software and associated documentation files 8 | * (the "Software"), to deal in the Software without restriction, 9 | * including without limitation the rights to use, copy, modify, merge, 10 | * publish, distribute, sublicense, and/or sell copies of the Software, 11 | * and to permit persons to whom the Software is furnished to do so, 12 | * subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be 15 | * included in all copies or substantial of portions the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 21 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 23 | * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | namespace HaskellCamargo\Maybe; 27 | 28 | interface JustInterface 29 | { 30 | } 31 | -------------------------------------------------------------------------------- /src/Maybe.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Permission is hereby granted, free of charge, to any person 7 | * obtaining a copy of this software and associated documentation files 8 | * (the "Software"), to deal in the Software without restriction, 9 | * including without limitation the rights to use, copy, modify, merge, 10 | * publish, distribute, sublicense, and/or sell copies of the Software, 11 | * and to permit persons to whom the Software is furnished to do so, 12 | * subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be 15 | * included in all copies or substantial of portions the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 21 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 23 | * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | namespace HaskellCamargo\Maybe; 27 | 28 | /** 29 | * This function applies construction for `Maybe` monad. It is able to detect 30 | * and return `Just _` or `Nothing`, wrapping the value in a monadic 31 | * constructor in case of success. 32 | * 33 | * @param mixed $value 34 | * 35 | * @return Just|Nothing 36 | */ 37 | function Maybe($value) 38 | { 39 | if ($value instanceof MaybeInterface) { 40 | return $value; 41 | } 42 | 43 | if (null === $value) { 44 | return new Nothing(); 45 | } 46 | 47 | return new Just($value); 48 | } 49 | -------------------------------------------------------------------------------- /src/MaybeInterface.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Permission is hereby granted, free of charge, to any person 7 | * obtaining a copy of this software and associated documentation files 8 | * (the "Software"), to deal in the Software without restriction, 9 | * including without limitation the rights to use, copy, modify, merge, 10 | * publish, distribute, sublicense, and/or sell copies of the Software, 11 | * and to permit persons to whom the Software is furnished to do so, 12 | * subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be 15 | * included in all copies or substantial of portions the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 21 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 23 | * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | namespace HaskellCamargo\Maybe; 27 | 28 | interface MaybeInterface 29 | { 30 | /** 31 | * Equivalent to Haskell's `>>=` operator. Its first argument is a value in 32 | * a monadic type, its second argument is a function that maps from the 33 | * underlying type of the first argument to another monadic type, and its 34 | * results is in that other monadic type. 35 | * 36 | * @param callable $fn 37 | * 38 | * @return MaybeInterface 39 | */ 40 | public function bind(callable $fn); 41 | 42 | /** 43 | * Extracts the element out of a `Just` and returns an error if its argument 44 | * is `Nothing`. 45 | * 46 | * @return mixed 47 | */ 48 | public function fromJust(); 49 | 50 | /** 51 | * Takes a `Maybe` value and a default value. If the `Maybe` is `Nothing`, it 52 | * returns the default values; otherwise, it returns the value contained in 53 | * the `Maybe`. 54 | * 55 | * @param $def 56 | * 57 | * @return mixed 58 | */ 59 | public function fromMaybe($def); 60 | 61 | /** 62 | * Returns true if its argument is of the form `Just _`. 63 | * 64 | * @return bool 65 | */ 66 | public function isJust(); 67 | 68 | /** 69 | * Returns false if its arguments is of the form `Nothing`. 70 | * 71 | * @return bool 72 | */ 73 | public function isNothing(); 74 | 75 | /** 76 | * Takes a default value, a function and, of course, a `Maybe` value. If the 77 | * `Maybe` value is `Nothing`, the function returns the default value. 78 | * Otherwise, it applies the function to the value inside the `Just` and 79 | * returns the result. 80 | * 81 | * @param $def 82 | * @param callable $fn 83 | * 84 | * @return mixed 85 | */ 86 | public function maybe($def, callable $fn); 87 | 88 | /** 89 | * Returns an empty list when given ``Nothing`` or a singleton list when not 90 | * given ``Nothing``. 91 | * 92 | * @see https://hackage.haskell.org/package/base-4.9.0.0/docs/src/Data.Maybe.html#maybeToList 93 | * 94 | * @return array 95 | */ 96 | public function toList(); 97 | } 98 | -------------------------------------------------------------------------------- /src/Nothing.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Permission is hereby granted, free of charge, to any person 7 | * obtaining a copy of this software and associated documentation files 8 | * (the "Software"), to deal in the Software without restriction, 9 | * including without limitation the rights to use, copy, modify, merge, 10 | * publish, distribute, sublicense, and/or sell copies of the Software, 11 | * and to permit persons to whom the Software is furnished to do so, 12 | * subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be 15 | * included in all copies or substantial of portions the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 21 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 23 | * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | namespace HaskellCamargo\Maybe; 27 | 28 | /** 29 | * `Nothing` is a constructor of the `Maybe` type/monad. It doesn't take value. 30 | */ 31 | class Nothing implements MaybeInterface, NothingInterface 32 | { 33 | /** 34 | * {@inheritdoc} 35 | */ 36 | public function bind(callable $fn) 37 | { 38 | return $this; 39 | } 40 | 41 | /** 42 | * {@inheritdoc} 43 | */ 44 | public function fromJust() 45 | { 46 | throw new \RuntimeException('Cannot call fromJust() on Nothing'); 47 | } 48 | 49 | /** 50 | * {@inheritdoc} 51 | */ 52 | public function fromMaybe($def) 53 | { 54 | return $def; 55 | } 56 | 57 | /** 58 | * {@inheritdoc} 59 | */ 60 | public function isJust() 61 | { 62 | return false; 63 | } 64 | 65 | /** 66 | * {@inheritdoc} 67 | */ 68 | public function isNothing() 69 | { 70 | return true; 71 | } 72 | 73 | /** 74 | * {@inheritdoc} 75 | */ 76 | public function maybe($def, callable $_) 77 | { 78 | return $def; 79 | } 80 | 81 | /** 82 | * {@inheritdoc} 83 | */ 84 | public function toList() 85 | { 86 | return []; 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/NothingInterface.php: -------------------------------------------------------------------------------- 1 | 5 | * 6 | * Permission is hereby granted, free of charge, to any person 7 | * obtaining a copy of this software and associated documentation files 8 | * (the "Software"), to deal in the Software without restriction, 9 | * including without limitation the rights to use, copy, modify, merge, 10 | * publish, distribute, sublicense, and/or sell copies of the Software, 11 | * and to permit persons to whom the Software is furnished to do so, 12 | * subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be 15 | * included in all copies or substantial of portions the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 21 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 23 | * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | namespace HaskellCamargo\Maybe; 27 | 28 | interface NothingInterface 29 | { 30 | } 31 | -------------------------------------------------------------------------------- /tests/MaybeTest.php: -------------------------------------------------------------------------------- 1 | assertEquals(true, $shouldBeNothing instanceof Maybe\Nothing); 14 | $this->assertEquals(true, $shouldBeJust instanceof Maybe\Just); 15 | } 16 | 17 | public function testBind() 18 | { 19 | $just = null; 20 | $nothing = null; 21 | 22 | $x = Maybe\Maybe(10)->bind(function ($num) use (&$just) { 23 | return $just = $num; 24 | }); 25 | 26 | $y = Maybe\Maybe(null)->bind(function ($num) use (&$just) { 27 | return $just = 10; 28 | }); 29 | 30 | $this->assertEquals(10, $just); 31 | $this->assertEquals(null, $nothing); 32 | 33 | $this->assertEquals(true, $x instanceof Maybe\Just); 34 | $this->assertEquals(true, $y instanceof Maybe\Nothing); 35 | } 36 | 37 | public function testFromJustPass() 38 | { 39 | $just = Maybe\Maybe(10); 40 | $this->assertEquals(10, $just->fromJust()); 41 | } 42 | 43 | /** 44 | * @expectedException Exception 45 | */ 46 | public function testFromJustFail() 47 | { 48 | $nothing = Maybe\Maybe(null); 49 | $nothing->fromJust(); 50 | } 51 | 52 | public function testFromMaybe() 53 | { 54 | $just = Maybe\Maybe(10); 55 | $nothing = Maybe\Maybe(null); 56 | 57 | $this->assertEquals(10, $just->fromMaybe(5)); 58 | $this->assertEquals(5, $nothing->fromMaybe(5)); 59 | } 60 | 61 | public function testIsJust() 62 | { 63 | $just = Maybe\Maybe(10); 64 | $nothing = Maybe\Maybe(null); 65 | 66 | $this->assertEquals(true, $just->isJust()); 67 | $this->assertEquals(false, $nothing->isJust()); 68 | } 69 | 70 | public function testIsNothing() 71 | { 72 | $just = Maybe\Maybe(10); 73 | $nothing = Maybe\Maybe(null); 74 | 75 | $this->assertEquals(false, $just->isNothing()); 76 | $this->assertEquals(true, $nothing->isNothing()); 77 | } 78 | 79 | public function testMaybe() 80 | { 81 | $just = Maybe\Maybe(10); 82 | $nothing = Maybe\Maybe(null); 83 | 84 | $this->assertEquals(25, $just->maybe(40, function ($num) { 85 | return $num + 15; 86 | })); 87 | 88 | $this->assertEquals(40, $nothing->maybe(40, function ($num) { 89 | return $num + 15; 90 | })); 91 | } 92 | 93 | public function testToList() 94 | { 95 | $just = Maybe\Maybe(10); 96 | $nothing = Maybe\Maybe(null); 97 | 98 | $this->assertEquals([10], $just->toList()); 99 | $this->assertEquals([], $nothing->toList()); 100 | } 101 | } 102 | --------------------------------------------------------------------------------