我正在尝试向 Paul Louth 学习 c# Language-ext。我发现 OptionAsync 类型非常方便,因为它将任务和替代项合并到一个 monad 中,从而使使用两者变得更加容易。
但我很困惑如何使用 OptionAsync 来等待。我认为 await OptionAsync
会返回一个选项,因为任务和选项是两个正交的概念。我觉得我真的在等待这个选项。但是,await OptionAsync 将返回 T 而不是选项。
我的问题是,我应该永远不会处于需要等待OptionAsync的情况吗?如果该选项为“无”,我该如何处理?我是否应该始终使用 OptionAsync 作为 monad 并且永远不要退出,其中可选性可能与 monad 中的任务一起处理?设计一定有它的道理。
I am trying to learn c# Language-ext from Paul Louth. I found the type OptionAsync is quite handy as it combines Tasks and Alternatives into one monad, making it a lot easier to work with both.
But I am confused how the await work with OptionAsync. I thought await OptionAsync<T>
would return an Option, as Task and Option are two orthogonal concepts. I feel I am really awaiting the Option. However, the await OptionAsync would return a T not the Option.
My question is, should I never be in the situatoin where await OptionAsync is needed? How do I deal with the option if it's a None? Should I always use OptionAsync as a monad and never get out, where the optionality is probably handled along with the Task in the monad? There must be reason for the design.
发布评论
评论(1)
当您“堆叠”两个 monad(例如
Task
和Option
)时,您会得到一个组合,该组合从其中包含的基础值中抽象出“效果”。例如,
OptionAsync
表示您可能有也可能没有异步传递的int
。 由于选项
而“可能或可能不会”,由于
异步
而“异步交付”
。这些就是效果。当您编写单子表达式(例如使用 可等待,您始终可以使用 monad 来做到这一点。
await
)时,您对单子“内部”的值进行操作 - 即T
。换句话说,您现在已经抽象出了效果,以便您可以专注于价值。我不太了解 LanguageExt,但我假设它使 OptionAsyncOption
的一般工作方式是,如果该值不存在,则整个表达式会短路,以便后续表达式不会运行。返回值也将是一个AsyncOption
值,如果一路上有任何一个值是None
,则最终结果也将是None
>。如果您确实想显式处理 的全部意义在于,您不必这样做 - 也许直到最后。
Option
值,只需使用Task
即可。将两者组合成 OptionAsync您可以使用
ToOption()
方法将OptionAsync
转换为Task
。Option
也称为Maybe
。考虑到这一点,也许我的文章异步注入很有用。至少,我试图在其中解释基本概念。When you 'stack' two monads (like
Task
andOption
) you get a combination that abstracts the 'effects' from the underlying value(s) contained in it.For instance,
OptionAsync<int>
indicates that you may or may not have anint
, asynchronously delivered. 'May or may not' because of theOption
, and'asynchronously delivered'
because of theAsync
. These are the effects.When you write monadic expression (e.g. with
await
) you operate on the value 'inside' of the monad - i.e. theT
. In other words, you've now abstracted away the effects so that you can focus on working on the value. I don't really know LanguageExt, but I'm assuming that it makesOptionAsync<T>
awaitable, which you can always do with a monad.The way
Option
works in general is that if the value isn't there, the entire expression short-circuits so that subsequent expressions don't run. The return value will also be anAsyncOption
value, and if any one of the values along the way wasNone
, the final result will also beNone
.If you really want to deal explicitly with the
Option
value, just work withTask<Option<T>>
. The whole point of combining the two intoOptionAsync<T>
is that you don't have to do that - until, perhaps, the very end.You can convert an
OptionAsync<T>
to aTask<Option<T>>
with theToOption()
method.Option
is also known asMaybe
. With that in mind, perhaps my article Asynchronous Injection is useful. In it, at least, I attempt to explain the underlying concepts.