F#中的协程

我刚刚开始使用F#开发Unity3D,并且我注意到,协同程序在书籍和教程中被大量使用,作为解决各种问题的巧妙解决方案。 我一直在试图弄清楚F#是否具有相同的内置结构,或者至少可以以某种方式模仿它们,但我无法在MSDN上找到任何东西。 我只发现了一些使用Continuation monad实现协程的文章,但这些作为初学者在我的脑海中处处可见。

以下是来自Unity文档的C#示例,它在游戏循环中重复调用时会导致对象的alpha颜色随着时间的推移以小增量褪色:

IEnumerator Fade() {
    for (float f = 1f; f >= 0; f -= 0.1f) {
        Color c = renderer.material.color;
        c.a = f;
        renderer.material.color = c;
        yield return;
    }

}

所以我只需要声明一个返回IEnumerator的函数,然后在我想要的内容中使用“yield”来切入控制。 我不知道如何在F#中执行此操作,因为我一直收到错误“此表达式预期具有IEnumerator类型,但这里有类型单位”。 “yield”关键字在F#中似乎也有不同的表现,因为与C#不同,它不能单独使用,并且必须位于序列表达式中,正如我从文档中理解的那样。

所以我错过了什么? 上面的功能如何在F#中实现?


UPDATE

古斯塔沃的解释是正确的。 下面是精确的Unity脚本,你可以附加到一个对象,看它的红色值在10秒的时间内减少0.1。

namespace CoroutinesExample
open UnityEngine

type CoroutinesExample() =
    inherit MonoBehaviour()

    member this.Start() =
        // Either of the these two calls will work
        // this.StartCoroutine("Fade") |> ignore
        this.Fade()                       

    member this.Fade() =
       seq { 
           for f in 1.f .. -0.1f .. 0.f do 
               let mutable c = this.renderer.material.color
               c.r <- f 
               this.renderer.material.color <- c
               yield WaitForSeconds(1.f) 
       } :?> IEnumerator

本文对解释Unity中协程的细节非常有帮助。


等效的F#代码如下:

member this.Fade() =
    seq {
        for f in 1.0 .. -0.1 .. 0.0 do
            let c = renderer.material.color
            c.alpha <- f
            renderer.material.color <- c
            yield ()
    } :> IEnumerable

请注意,与C#不同,您必须产生一些价值,所以我们使用单位( () )。 seq表达式的类型为seq<unit> ,它是IEnumerable<Unit>的别名。 为了使它符合Unity所期望的类型,我们只需要使用:> IEnumerable对它进行重播:> IEnumerable

链接地址: http://www.djcxy.com/p/53163.html

上一篇: Coroutines in F#

下一篇: Why having a syntaxless string or integer doesn't throw syntax error?