yitznewton / maybe-php
PHP的Maybe monad实现
0.2.2
2014-11-03 02:23 UTC
Requires
- php: >=5.4
Requires (Dev)
- fabpot/php-cs-fixer: dev-master
- phpmd/phpmd: ~2.0
- phpunit/phpunit: ~4.0
- squizlabs/php_codesniffer: ~1.0
This package is not auto-updated.
Last update: 2024-09-10 02:30:06 UTC
README
PHP的Maybe monad实现
此项目完全受@linepogl的一篇博客文章启发。
动机
处理null
值(在PHP中,还有假值)既繁琐又容易出错(例如空指针异常,尝试解引用一个null
)。
在我接触Haskell的过程中,我了解到了模式匹配的神奇之处,你可以让编译器强制你处理所有可能性。这结合了名为Maybe
的工具,要求对“null”和“非null”可能性进行特定处理。
PHP不提供模式匹配,但我们可以使用类来包装原始值,并要求我们处理null条件,而无需重复显式检查null和条件。
示例
简单
之前
$blogpost = $repository->get($blogpostId); echo $blogpost->teaser(); // oh noe! what if $blogpost is null?! :boom:
之后
$blogpost = new \Yitznewton\Maybe\Maybe($repository->get($blogpostId)); echo $blogpost->select(function ($bp) { $bp->teaser(); })->valueOr('No blogpost found');
带回调
$blogpost = new \Yitznewton\Maybe\Maybe($repository->get($blogpostId)); $callback = function () { return someExpensiveOperation(); }; echo $blogpost->select(function ($bp) { $bp->teaser(); })->valueOrCallback($callback);
宽松的假值
// $process->execute() normally returns a result object, but sometimes returns false $result = new LooseMaybe($process->execute()); echo $result->select(function ($resultObject) { $resultObject->getStatus(); })->valueOr('failed'); // echoes 'failed' when the result was false
性能
在PHP 5.5的一个简单测试中,性能大约是直接在if/else条件中使用is_null()
检查的20%。换句话说,它运行的时间是5倍。
您可以通过运行PHPUnit的配置测试套件在本地重现测试。您首先需要安装XHProf,并使用本地的phpunit.xml
配置覆盖XHProf库目录。
$ ./vendor/bin/phpunit --testsuite=profiling
字典包装器
maybe-php包括一个名为Dictionary
的数组包装器,尝试访问包装器的属性将返回一个Maybe
对象。您可以指定返回一个普通的Maybe
(默认)或LooseMaybe
。
$dictionary = new \Yitznewton\Maybe\Dictionary([ 'foo' => 'bar', ]); $dictionary->foo->valueOr('quux'); // 'bar' $dictionary->noSuchKey->valueOr('quux'); // 'quux' // with LooseMaybe $dictionary = new \Yitznewton\Maybe\Dictionary([ 'foo' => false, ], \Yitznewton\Maybe\LooseMaybe::class); $dictionary->foo->valueOr('quux'); // 'quux', because loose falsy