yitznewton/maybe-php

PHP的Maybe monad实现

0.2.2 2014-11-03 02:23 UTC

This package is not auto-updated.

Last update: 2024-09-10 02:30:06 UTC


README

Travis build status PHP 5.3 not supported PHP 5.4 supported PHP 5.5 supported PHP 5.6 supported HHVM tested BSD 2-Clause license

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