F# F中两个观测值的组合#
我很难理解如何管理相互依赖的多个观测值。我想定义一个具有以下签名的函数:F# F中两个观测值的组合#,f#,observable,F#,Observable,我很难理解如何管理相互依赖的多个观测值。我想定义一个具有以下签名的函数: clock:IObservable<unit> -> obs:IObservable<'a> -> IObservable<'a> clock:IObservable->obs:IObservable 因此,obs的事件只能在每个时钟周期内发出一次,obs的多余事件将被丢弃 我曾尝试映射两个观察值,然后将它们合并到一个流中,但这不是解决方案。用于观察值的内置F#库
clock:IObservable<unit> -> obs:IObservable<'a> -> IObservable<'a>
clock:IObservable->obs:IObservable
因此,obs的事件只能在每个时钟周期内发出一次,obs的多余事件将被丢弃
我曾尝试映射两个观察值,然后将它们合并到一个流中,但这不是解决方案。用于观察值的内置F#库只有几个基本函数,因此使用内置原语很难做到这一点。您可能可以使用完整的Rx库中的函数,该函数具有良好的性能,并且具有大量的操作(但这使您很难确定哪一个是您需要的)
另一种纯粹的F#方法是使用基于代理的编程。这使您能够很好地处理复杂的并发模式。下面实现了一个代理,它将勾选
和事件
作为两种消息。它记住最后一个事件
,当勾选
发生时,它用最后一个事件
值触发返回的可观察值:
open System
type WhenTickMessage<'T> =
| Tick
| Event of 'T
let whenTick (clock:IObservable<_>) (event:IObservable<_>) =
let result = new Event<_>()
let agent = MailboxProcessor.Start(fun inbox ->
let rec loop event = async {
let! msg = inbox.Receive()
match msg with
| Tick ->
event |> Option.iter (fun e -> result.Trigger(e))
return! loop None
| Event e ->
return! loop (Some e) }
loop None)
clock.Add(fun _ -> agent.Post Tick)
event.Add(fun e -> agent.Post (Event e))
result.Publish
开放系统
键入WhenTickMessage
让rec循环事件=异步{
let!msg=inbox.Receive()
配味精
|勾选->
event |>Option.iter(乐趣e->result.Trigger(e))
返回!无循环
|活动e->
return!循环(一些e)}
循环(无)
clock.Add(趣味->agent.Post勾选)
添加事件(乐趣e->agent.Post(事件e))
结果。发布
我认为仅仅使用F#的内置Observable
支持是不容易的,但是看看反应式扩展中的Observable.WithLatestFrom()
。(要获得更为F友好的API,请查看NuGet包FSharp.Control.Reactive
)