php - 管道函数的意外输出
问题描述
我正在尝试在 PHP 上模拟 Maybe 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
闭包之后的下一次调用中,这将为您的输出添加 1 null + 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;
推荐阅读
- reactjs - Apollo useReactiveVar 抛出 TypeError: rv.onNextChange is not a function
- web - 从网站打开并向身份验证应用程序发送数据
- winapi - WM_MOUSEMOVE / wParam 不包含键状态,仅当按下任何鼠标按钮时
- html - 内容不会将大小调整为 pagewrapper
- javascript - 使用 HTML + JS 进行动态搜索
- javascript - 检查类是否包含jQuery中的类
- sql - 如何在 SQL 中从一张表编写双重查询
- python - 尝试在 pytorch 中使用经过训练的 FNN 模型时出现运行时错误(mat1 和 mat2....)
- python-3.x - 我的代码一直循环最后一部分并且不会打印
- mongodb - 在 fastify-session 上编写 set/get/destroy 方法以将会话存储到 MongoDB 中?