I'm learning F# and have a couple of routines much of whose functionality looks common so I am looking to refactor them together.Here are the routines (which for the record I lifted from elsewhere:let Prices time ID (polling:float) =   let sync = System.Threading.SynchronizationContext.Current  let obs = new Event<int>()   let raiseEvent (value:int) = sync.Post((fun _ -> obs.Trigger(value)), null)    let interval = TimeSpan.FromSeconds(polling)  let rec loop nextTime= async {     // Generate next value (on the GUI thread)        do getPrices nextTime      |> List.filter (fun price -> price.ID = ID)      |> List.iter (fun price -> raiseEvent price.Price)                            // Wait some short time    do! Async.Sleep(1000)    // Continue looping    do! loop (nextTime.Add(interval)) }    loop time |> Async.Start    obs.Publishand let Volumes time ID (polling:float) =   let sync = System.Threading.SynchronizationContext.Current  let obs = new Event<VolumeDTO>()   let raiseEvent (value:VolumeDTO) = sync.Post((fun _ -> obs.Trigger(value)),  null)    let interval = TimeSpan.FromSeconds(polling)  let rec loop nextTime= async {     // Generate next value (on the GUI thread)        do getVolumes nextTime      |> List.filter (fun volume -> volume.ID = ID)      |> List.iter (fun volume -> raiseEvent volume)                            // Wait some short time    do! Async.Sleep(1000)    // Continue looping    do! loop (nextTime.Add(interval)) }    loop time |> Async.Start     obs.PublishThe external function calls are hopefully reasonable self explanatory retrieving data from a dblet getPrices lastTime =  createList<PriceDTO>((getPriceSql lastTime), priceReader)let getVolumes lastTime =  createList<VolumeDTO>((getVolumeSql lastTime), volumeReader)The types are very simple, but I'm not sure I've got this 'right':type IID =  abstract member ID : int64type PriceDTO(ID:int64, Price:int) =   interface IID with    member this.ID = ID  member x.ID = ID  member x.Price = Pricetype VolumeDTO(ID:int64, Amount:decimal, Price:int32) =   interface IID with    member this.ID = ID  member x.ID = ID  member x.Amount = Amount  member x.Price = PriceI've played around with something but I'm not at all there as yet:let publish<'a> time ID (polling:float) dataRetriever =   let sync = System.Threading.SynchronizationContext.Current  let obs = new Event<'a>()   let raiseEvent (value:'a) = sync.Post((fun _ -> obs.Trigger(value)), null)    let interval = TimeSpan.FromSeconds(polling)  let rec loop (nextTime:DateTime)= async {     // Generate next value (on the GUI thread)        do dataRetriever nextTime      |> List.filter (fun item -> item.ID = ID)      |> List.iter (fun item -> raiseEvent item)                            // Wait some short time    do! Async.Sleep(1000)    // Continue looping    do! loop (nextTime.Add(interval)) }    loop time |> Async.Start     obs.PublishI may well have not quite implemented this correctly. I'm obviously getting a list of prices or volumes filtering them and publishing them. In order to achieve the filtering I've created an interface, but I'm not really happy with this since I'd prefer to keep the DTOs as simple as possible. Intellisense is telling me that my dataRetriever function takes a DateTime and returns an 'a list, but I'm not sure I quite want that since I need to cast it to an IID interface for filtering and then back to the underlying DTO for publishing.Is there a more 'functional' (or perhaps just better) way to do this?
Getting prices and volume
f#