我正在尝试在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
一些聪明的灵魂能照亮我吗?
答案 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;