gpt4 book ai didi

具有至少一个元素的 F# 序列

转载 作者:行者123 更新时间:2023-12-03 09:52:41 29 4
gpt4 key购买 nike

F#初学者在这里

我想创建一个类型,它是具有至少一个元素的另一种具体类型(事件)的序列。任何其他元素都可以在以后随时添加。通常在 C# 中,我会创建一个具有私有(private) List 和公共(public)方法的类。

但我想用一种功能性的方法来做,而不是模仿 C# 方法。或者至少尝试一下。

我的思路:

  • 让我们创建一个“of seq”类型并给它一个需要 Event 类型实例的构造函数
    type Event = Event of string

    type PublishedEvents = EventList of seq<Event> with
    static member create (event:Event) = EventList(Seq.singleton event)
  • 现在让我们添加一个“add”方法来添加另一个可选的 Event 实例
    type PublishedEvents with
    member this.add(event:Event) = Seq.append this [event]

  • 但这不起作用,F# 提示“this”与 seq<'a> 不兼容。

    所以我尝试了这个:
    type PublishedEvents with
    member this.add (event:Event) : PublishedEvents = EventList(Seq.append this [event])

    现在它提示“this”与 seq 不兼容...这让我很困惑,因为上面几行说 EventList of seq<Event> ...所以我想我需要以某种方式转换 EventList返回 seq<Event>所以我可以使用 Seq.append ?
    let convertFunction (eventList:PublishedEvents) : seq<Event> = ???

    但我不知道该怎么做。

    我是否走对了方向?模仿带有支持字段的 C# 类会更好吗?还是我错过了什么?

    最佳答案

    实际的事件序列包含在 EventList 中。歧视工会案。

    您可以像这样打开它并重新包装它:

    type PublishedEvents with
    member this.add(event:Event) =
    match this with
    | EventList events -> Seq.append events [event] |> EventList

    但是,我不得不质疑创建这个 PublishedEvents 的值(value)。首先输入,如果它只是一个 EventList case 包含一个要求您重复包装和展开值的序列。

    另外,请注意 add方法不会改变现有的 PublishedEvents .由于 Seq.append 的方式,它创建了一个具有新事件序列的新事件。有效,因为 seq<'a>实际上只是 F# 的 System.Collections.Generic.IEnumerable<'a>) 的名称.

    此外,您的方法不会阻止创建非空事件序列。 EventListPublishedEvents 的公共(public)构造函数所以你可以写:
    EventList []

    使类型系统强制执行非空序列的一种简单方法是:
    type NonEmptySeq<'a> = { Head : 'a; Tail : seq<'a> } with
    static member Create (x:'a) = { Head = x; Tail = [] }
    member this.Add x = { this with Tail = Seq.append this.Tail [x] }

    let a = NonEmptySeq.Create (Event "A")
    let b = a.Add (Event "B")

    但同样,这些序列是不可变的。你可以用 C# List<'a> 做类似的事情如果你需要突变。在 F# 中,它被称为 ResizeArray<'a> :
    type NonEmptyResizeArray<'a> = { Head : 'a; Tail : ResizeArray<'a> } with
    static member Create (x:'a) = { Head = x; Tail = ResizeArray [] }
    member this.Add x = this.Tail.Add x

    let a = NonEmptyResizeArray.Create (Event "A")
    a.Add (Event "B")

    关于具有至少一个元素的 F# 序列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51151120/

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