gpt4 book ai didi

casting - F#:转换 seq <'A> to seq<' B> 的最快方法

转载 作者:行者123 更新时间:2023-12-01 00:31:21 25 4
gpt4 key购买 nike

我将 Marten 用作事件存储,特别是用于获取事件流。

type AccountCreation = {
Owner: string
AccountId: Guid
CreatedAt: DateTimeOffset
StartingBalance: decimal
}

type AccountEvents =
| AccountCreated of AccountCreation
| AccountCredited of Transaction
| AccountDebited of Transaction

let settings = {
Host = "localhost"
DatabaseName = "postgres"
UserName = "root"
Password = "root"
EventTypes = eventTypes
}
use store = createDocumentStore settings
use session = store.LightweightSession()

let khalidId = Guid.NewGuid()
let billId = Guid.NewGuid()

let khalid = AccountEvents.AccountCreated({
Owner = "Khalid Abuhakmeh"
AccountId = khalidId
StartingBalance = 1000m
CreatedAt = DateTimeOffset.UtcNow
})

let bill = {
Owner = "Bill Boga"
AccountId = billId
StartingBalance = 0m
CreatedAt = DateTimeOffset.UtcNow
}

session.Events.Append(khalidId, khalid) |> ignore
session.Events.Append(billId, bill) |> ignore

session.SaveChanges()

let stream = session.Events.FetchStream()

stream正在IReadOnlyList<IEvent>IEvent定义为:

public interface IEvent
{
Guid Id { get; set; }
int Version { get; set; }
long Sequence { get; set; }
object Data { get; }
Guid StreamId { get; set; }
string StreamKey { get; set; }
DateTimeOffset Timestamp { get; set; }
string TenantId { get; set; }
void Apply<TAggregate>(TAggregate state, IAggregator<TAggregate> aggregator) where TAggregate : class, new();
}

我想转换每个 IEventAccountEvents ,如果 Data 的基础类型属性是 AccountEvents (如果不是,则该项目不会在结果序列中产生)。

在 C# 中,我会简单地使用关键字 as来实现这一目标,但在 F# 中,我不确定什么是最快的 F#-ish 方式(就性能而言)。

我最终得到了以下代码:

let seqCastOption<'T> sequence =
sequence
|> Seq.map(fun x ->
match box x with
| :? 'T as value -> Some value
| _ -> None)

let fetchStream<'T> (session: IDocumentSession) (id: Guid) =
let stream = session.Events.FetchStream(id)
stream
|> Seq.map(fun x -> x.Data)
|> seqCastOption<'T>
|> Seq.filter (fun x -> x.IsSome)
|> Seq.map(fun x -> x.Value)

但这似乎相当“昂贵”,我想知道转换 .Data 的步骤是否到 Option<AccountEvents> + 过滤那些IsSome可以一次完成。

最佳答案

Seq.choose rmunn 的回答中提到的函数对于了解这种情况非常有用,但对于这种确切情况,我建议使用内置的 .NET 方法 Enumerable.OfType<'T> ,这正是您想要的,并且可能已经过优化:

open System.Linq

let fetchStream<'T> (session: IDocumentSession) (id: Guid) =
let stream = session.Events.FetchStream(id)
stream
|> Seq.map(fun x -> x.Data)
|> Enumerable.OfType<'T>

关于casting - F#:转换 seq <'A> to seq<' B> 的最快方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56475389/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com