Arrow和Monad,两个独立的视点来组成计算?
我读过 Brent Yorgey 在 Monad.Reader 中写的“The Typeclassopedia” #13,发现“Functor层次结构”与“Category层次结构”相互依赖,如图1所示。
而且根据作者的说法,ArrowApply == Monad
,尤其是前一个只是一个类型类实例,可以在以下情况下使用:
“我们希望能够根据中间结果计算出一个箭头,并使用这个计算出的箭头继续计算。这是 ArrowApply 赋予我们的能力。”
但我们怎样才能把这些东西放在一起呢?我的意思是 Monad 和 Arrow 中都有一些流程控制函数(例如 if
和 else
与 ArrowChoice
或 forM< /code> 与
ArrowLoop
),并且 Monad 中的某些功能似乎“缺失”((***)
,(|||)
或首先
)。所有这些看起来就像我们需要在使用 Monad 或 Arrow 系统来构建我们的副作用计算流程之间做出选择,并且会失去另一个系统中的一些功能。
I've reading the "The Typeclassopedia" by Brent Yorgey in Monad.Reader#13 ,and found that "the Functor hierachy" is interdependent of "the Category hierachy" as the Figure.1 shown.
And according to the author, ArrowApply == Monad
, especially that the previous one is just a type class instance that can be used when
"we would like to be able to compute an arrow from intermediate results, and use this computed arrow to continue the computation. This is the power given to us by ArrowApply."
But how can we put these things together ? I mean that there are some flow control functions both in Monad and Arrow ( like if
and else
vs. ArrowChoice
, or forM
vs. ArrowLoop
), and some features seem like "missing" in Monad ( (***)
,(|||)
or first
). All these are seem like that we need to make a choice between using Monad or Arrow system to construct our side effect computation flow, and will lose some features in another system.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
答案如下(所有这些都来自 Control.Arrow 文档)
ArrowMonad
新类型是我们为ArrowApply
箭头定义Monad
实例的载体。我们本来可以使用,但这会导致 Haskell 的有限类型类推断出现问题(我认为它可以与 UndecideableInstances 扩展一起使用)。
您可以将
ArrowApply
箭头的Monad
实例视为将单子操作转换为等效的箭头操作,如源代码所示:所以知道我们知道
ArrowApply
与Monad
一样强大,因为我们可以在其中实现所有Monad
操作。令人惊讶的是,反之亦然。这是由 @hammar 指出的Kleisli
新类型给出的。观察:前面给出了使用 monad 操作的所有常见箭头操作的实现。
(***)
没有被提及,因为它有一个使用first
和second
的默认实现:所以现在我们知道如何实现箭头 (< code>Arrow、
ArrowChoice
、ArrowApply
)使用 Monad 操作进行操作。回答你关于为什么我们同时拥有
Monad
和Arrow
的问题(如果它们是等价的):当我们不需要箭头的全部功能时,功能较弱的箭头很有用。 monad,就像应用函子一样有用。尽管
ArrowApply
和Monad
是等效的,但没有app
的Arrow
或ArrowChoice
是在Monad
层次结构中无法表示的东西。反之亦然,Applicative
无法在箭头层次结构中表示。这是因为
ap
在 monad 层次结构中是“第一个”,在箭头层次结构中是“最后一个”。单子世界和箭头世界之间的主要语义区别在于箭头捕获转换(
arr b c
意味着我们从b
生成c
),而 monad 捕获一个操作(monad a
生成一个a
)。这种差异在Kleisli
和ArrowMonad
新类型中得到了很好的体现:在
Kleisli
中,我们必须添加源类型a
,并在ArrowMonad
中我们将其设置为()
。我希望这能让您满意!
The answer lies in the following (all of this is from the Control.Arrow docs)
The
ArrowMonad
newtype is the vehicle with which we define theMonad
instance forArrowApply
arrows. We could have usedbut this would've caused problems with Haskell's limited type class inference (It would work with the
UndecideableInstances
extension, I fathom).You can think of the
Monad
instance forArrowApply
arrows as translating monadic operations into equivalent arrow operations, as the source shows:So know we know that
ArrowApply
is as powerful asMonad
since we can implement all of theMonad
operations in it. Surprisingly, the converse is also true. This is given by theKleisli
newtype as @hammar noted. Observe:The previous gives implementations for all of the usual arrow operations using monad operations.
(***)
is not mentioned since it has a default implementation usinfirst
andsecond
:So now we know how to implement arrow (
Arrow
,ArrowChoice
,ArrowApply
) operations using Monad operations.To answer your question about why we have both
Monad
andArrow
if they turn out to be equivalent:The less powerful arrows are useful when we do not need the full power of a monad, just like applicative functors can be useful. And even though
ArrowApply
andMonad
are equivalent, anArrow
orArrowChoice
withoutapp
is something that is not representable in theMonad
hierarchy. Vice versa, anApplicative
is not representable in the arrow hierarchy.This is because
ap
comes "first" in the monad hierarchy and "last" in the arrow hierarchy.The main semantic difference between the monad and arrow worlds is that arrows capture a transformation (
arr b c
means we produce ac
from ab
), while monads capture an operation (monad a
produces ana
). This difference is reflected well in theKleisli
andArrowMonad
newtypes:In
Kleisli
we have to add the source typea
, and inArrowMonad
we set it to()
.I hope this satisfies you!