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