中间件单子?

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的中间件中添加功能。

所以我可以ma​​p(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 函数。

如果您想在中间进行更改,您可能必须自己动手,但这并不意味着您必须按顺序指定具体函数。如果我希望能够在最后一刻从您的示例中指定 hi,我将部分应用如下函数:

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)

有一些方法可以使这样的东西更通用,但通常越简单越好。

【讨论】:

以上是关于中间件单子?的主要内容,如果未能解决你的问题,请参考以下文章

锐浪报表打出来第二页老有锐浪客户端几个字出来?

这是一个啥样的结构? (具有部分逆但不是共单子的单子)

如何在种类的单子中重复单子指令?

单子设计模式(Singleton pattern)

场景代码题:有200个骑手都想要抢这⼀个外卖单子,如何保证只有一个骑手接到单子?

场景代码题:有200个骑手都想要抢这⼀个外卖单子,如何保证只有一个骑手接到单子?