如何编写 Monad 将计算链接在一起
我正在编写我的第一个 monad 实例,所以如果我遗漏了一些明显的东西,请原谅。
我想做这样的事情:
readStuffFromDatabase >>= function1 >>= ... >>= functionN >>= writeStuffToDatabase
function1 ... functionN 是业务逻辑。任何业务逻辑都可以返回 DoNothing,这显然会阻止任何进一步的计算。
以下是我的问题:
我是否以正确的方式思考这个问题?这种方法能否带来惯用的代码、良好的性能等,还是已经注定了?
我应该如何定义一个类型来将任意数量的计算链接在一起?对我来说模糊的是所有 monad 实例都已经这样做了,而我需要的只是一个普通的 monad 实例吗? (比如也许?)或者我需要更复杂的东西吗?
I am writing my first monad instance so please forgive if I'm missing something obvious.
I want to do something like this:
readStuffFromDatabase >>= function1 >>= ... >>= functionN >>= writeStuffToDatabase
function1 ... functionN are business logic. Any business logic can return DoNothing which should obviously prevent any further computation.
Here are my questions:
Am I thinking about the problem in the right way? Can this approach lead to idiomatic code, good performance, etc. or is it already doomed?
How should I define a type intended to chain arbitrary amounts of computation together? What's fuzzy to me is do all monad instances already do that and all I need is a vanilla monad instance? (Like Maybe?) Or do I need something more sophisticated?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
简短版本:
Monad
几乎肯定会把你逼到墙角。您需要Applicative
相反,或者最多是一个选择性的应用程序。假设您选择一个 monad,将其命名为
M
,并执行一些类似numEmployees :: M Int
之类的操作。现在我写道:要执行此操作,您需要在知道
n
之前决定是否采用else
分支。不可能。此处妨碍您的 monad 的基本特征是,后续操作可以在决定要做什么之前检查早期操作返回的值。应用函子不支持这一点,因此更适合您希望进行的静态分析。
Short version:
Monad
is almost certainly going to paint you into a corner. You needApplicative
instead, or at most, a selective applicative.Suppose you go for a monad, name it
M
, and have some action likenumEmployees :: M Int
or something. Now I write:To execute this action, you need to decide whether the
else
branch gets taken before knowingn
. Not possible.The fundamental feature of monads that's in your way here is that later actions can inspect the values returned by earlier actions before deciding what to do. Applicative functors do not support that, and so are more amenable to the kind of static analysis you're hoping to do.