管道功能输出异常

时间:2019-07-07 10:18:28

标签: php functional-programming

我正在尝试在PHP上模拟Maybe monad,但我无法理解我编写的管道函数的输出。

代码受Eric Elliott's article的启发。

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

api.tests.csproj //valid
someOthers.tests.csproj //valid

GDS.tests.csproj //not valid (skip)

预期结果如下:

<?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

一些聪明的灵魂能照亮我吗?

1 个答案:

答案 0 :(得分:1)

首先,预期结果不应类似于:

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);,该语句什么也没调用

您需要改为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;