F#: 我如何在 Async<'T> 中包装一个非异步值?

huangapple go评论79阅读模式
英文:

F#: How can I wrap a non-async value in Async<'T>?

问题

在F#中,我正在实现一个返回Async<'T>的接口,但我的实现不需要任何异步方法调用。以下是我的当前实现示例:

type CrappyIdGeneratorImpl() =
    interface IdGenerator with
        member this.Generate(): Async<Id> = async {
            return System.Guid.NewGuid().ToString()
        }

这是将非Async<>值包装为Async<>的"最佳"方法吗?还是有更好的方法?

换句话说,我正在寻找AsyncSystem.Threading.Tasks.Task.FromResult()的等效方法。

英文:

In F#, I'm implementing an interface that returns Async<'T>, but my implementation does not require any async method calls. Here's an example of my current implementation:

type CrappyIdGeneratorImpl() =
    interface IdGenerator with
        member this.Generate(): Async&lt;Id&gt; = async {
            return System.Guid.NewGuid().ToString()
        }

Is this the "best" way to wrap a non-Async<> value in Async<>, or is there a better way?

Put another way, I'm looking for the Async equivalent of System.Threading.Tasks.Task.FromResult().

答案1

得分: 1

是的,这是最好的方式。

请注意,正如注释中所述,另一种方法是使用 async.Return,但它并不完全相同,在您的用例中它不会起作用,因为参数会被急切地评估。

在您的情况下,您希望每次运行异步时调用 .NewGuid() 方法,但如果您仅使用 async.Return,它将被评估一次,异步计算将以该结果作为固定值创建。

实际上,与CE等效的方式是 async.Delay (fun () -> async.Return (.. 您的表达式 ..))

更新

正如Tarmil指出的,鉴于代码位于方法中,这可以被解释为预期的方式。

也许您创建方法是因为这是您处理任务的方式,但是异步可以独立创建和调用(热 vs 冷异步模型)。

关于意图是延迟异步还是在每次方法调用时创建异步的问题,我并不完全清楚,但无论哪种情况,上述关于每种方法的解释仍然有效。

英文:

Yes, that's the best way.

Note that, as stated in the comment, another way would be to do async.Return but it's not exactly the same thing, and in your use case it won't work, due to eager evaluation of the argument.

In your case you're interested in calling the .NewGuid() method each time the async is run, but if you use async.Return alone it will be evaluated once and the async computation will be created with that result as a fixed value.

In fact the equivalent of the CE is async.Delay (fun () -&gt; async.Return (.. your expression ..))

UPDATE

As Tarmil noted, this can be interpreted as intended, given that the code resides in a method.

It might be the case that you created a method because that's the way you do with tasks, but Asyncs can be created and called independently (hot vs cold async models).

The question of whether the intention is delaying the async or creating an async at each method call is not entirely clear to me, but whichever is the case, the explanation above about each approach is still valid.

huangapple
  • 本文由 发表于 2023年2月6日 05:25:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/75355622.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定