中间件单子?
Posted
技术标签:
【中文标题】中间件单子?【英文标题】:Middleware monad? 【发布时间】:2021-10-14 04:53:24 【问题描述】:我是在 javascript 中尝试函数式编程的新手。
我正在学习和使用 monad(Reader、State、Fluture ...)来用纯函数编写我的 Node 应用程序。
但我经常觉得需要一种数据结构,类似于 Monad,但我可以在中间件中链接函数。
把它想象成两个函数的结构
f: a->d
g: d->b
运行就像组合两个函数 g(f(x))
但我想要一个类似地图的方法在2的中间件中添加功能。
所以我可以map(h)(i)(m)
在哪里
h: d -> e
i: e -> d
运行映射结构我得到 g(i(h(f(x))))
我曾尝试在 JS 库或论文甚至 haskel 世界中搜索此国王的数据结构,但一无所获。我错过了什么?还是有一种更简单的方法来以“中间件”方式组合函数而无需实现专用的 monad?
【问题讨论】:
m
中的map(h)(i)(m)
是什么?
当然,你可以写一个函数map
来做你想做的事。它不必是一个单子。
map(h) (i) (m)
应该是 map(x => h(i(x))) (m)
,其中第一个参数是一个任意复杂的反向函数组合,类型为 d -> d
。但是,这样的组合是静态的,即您不能跳过中间的函数。
可以实施,但会是一个很好的做法还是有更好的解决方案? It 的一个用例可能是有一个惰性函数,我可以在其中映射输出结果,但甚至可以使用“中间件”函数更改输入参数。例如,用于 sql 查询的 monad,您可以在其中映射和处理结果,并在最终运行之前在不同时刻更改输入参数。
@IvenMarquardt 更少的静态替代方案?
【参考方案1】:
如果你想映射输出,那就是协变函子的map
函数。
如果您想要映射输入,那是逆变函子的 contramap
函数。
如果您想在中间进行更改,您可能必须自己动手,但这并不意味着您必须按顺序指定具体函数。如果我希望能够在最后一刻从您的示例中指定 h
和 i
,我将部分应用如下函数:
const query = f => g => h => i => x => g(i(h(f(x))))
const partial = query(f)(g)
// Later on...
const withHAndI = partial(h)(i)
// Even later...
const result = withHAndI(x)
有一些方法可以使这样的东西更通用,但通常越简单越好。
【讨论】:
以上是关于中间件单子?的主要内容,如果未能解决你的问题,请参考以下文章