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
上一篇: Coroutines in F#
下一篇: Why having a syntaxless string or integer doesn't throw syntax error?