管道功能上的意外输出



我正在尝试模仿PHP上的Monad,我无法理解我写的管道功能的输出。

该代码的灵感来自埃里克·埃利奥特(Eric Elliott(的文章。

php -v//php 7.2.19-0 ubuntu0.18.04

<?php   
function pipe_map(...$fns) {
    return function ($value) use ($fns) {
        return array_reduce($fns, function ($prev, $next) {
            return $prev->map($next);
        }, $value);
    };
};
class Maybe {
    private $value;
    public function __construct($value) {
        $this->value = $value;
    }
    private function doesExist() {
        return !empty($this->value);
    }
    public function map(callable $fn) {
        return $this->doesExist()
            ? new Maybe($fn($this->value))
            : new Maybe(NULL);
    }
    public function join() {
        return $this->value;
    }
}
$add1 = function ($value) {
    return $value + 1;
};
$trace = function ($label) {
    return function ($value) use ($label) {
        print_r($label . $value . "n");
        return $value;
    };
};
$mult2 = function ($value) {
    return $value * 2;
};
$bad_result = function ($value) {
    echo "bad computation happens n";
};
$maybe3 = new Maybe(3);
$result = pipe_map(
    $trace("Value is now: "),
    $add1,
    $trace("Value is now: "),
    $bad_result,
    $trace("Value is now: "),
    $add1,
    $trace("Value is now: "),
    $mult2,
    $trace("Value is now: ")
)($maybe3);

?>

预期的结果是:

Value is now: 3
Value is now: 4
bad computation happens
Value is now: 
Value is now: 
Value is now: 

但是我得到了:

Value is now: 3
Value is now: 4
bad computation happens 

我期望调用$bad_result功能后放置的功能,但显然不是。

打印$result变量时输出为:

print_r($result);
// Maybe Object
// (
//     [value:Maybe:private] => 
// )
var_dump($result->join());
// NULL

一些明亮的灵魂可以照亮我吗?

首先,预期的结果不应该是:

Value is now: 3
Value is now: 4
bad computation happens
Value is now: 
Value is now: 
Value is now: 

这是因为在$bad_result之后的下一个通话中,您正在调用add1闭合,该闭合将在您的输出null + 1 = 1中加1个。

所以预期的结果应该是

Value is now: 3
Value is now: 4
bad computation happens
Value is now:
Value is now: 1
Value is now: 2

这一切都发生了,因为您正在返回new Maybe(NULL);

在您只是不调用错误时,您期望如何在计算错误之后执行回调?

请记住,从$bad_result回调开始,您要获得的null,因此map方法的每个调用都将始终执行else语句,该语句是new Maybe(NULL);,该语句nothing noth nather。

您需要使用Maybe($fn(null));,以确保您可以为每个迭代拨打可可。


获得确切的预期结果:

Value is now: 3
Value is now: 4
bad computation happens
Value is now: 
Value is now: 
Value is now: 

您需要在关闭中验证$value,特别是add1关闭。

类似:

return !$value ? null : $value + 1;

最新更新