Фактическая последовательность событий заключена в EventList
дискриминируемый случай объединения.
Вы можете развернуть его и перемотать так:
type PublishedEvents with
member this.add(event:Event) =
match this with
| EventList events -> Seq.append events [event] |> EventList
Однако я должен сначала усомниться в ценности создания этого типа PublishedEvents
, если это всего лишь один EventList
случай, содержащий последовательность, которая требует от вас повторять или разворачивать значения.
Также имейте в виду, что этот метод add
не меняет существующий PublishedEvents
. Он создает новый с новой последовательностью событий из-за способа, которым работает Seq.append
, потому что seq<'a>
на самом деле является просто именем F # для System.Collections.Generic.IEnumerable<'a>)
.
Кроме того, ваш подход не предотвращает создание непустой последовательности событий. EventList
является открытым конструктором для PublishedEvents
, поэтому вы можете просто написать:
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")