Skip to content

Instantly share code, notes, and snippets.

@BashkaMen
Created April 19, 2021 12:12
Show Gist options
  • Save BashkaMen/15783eebe000af81844d68bb23edbe85 to your computer and use it in GitHub Desktop.
Save BashkaMen/15783eebe000af81844d68bb23edbe85 to your computer and use it in GitHub Desktop.
module Application.ES
open System
open FsToolkit.ErrorHandling
let inline ( ^ ) f x = f x
type CommandMeta<'id, 'command> = { AggId: 'id; Command: 'command }
type EventMeta<'id, 'payload> = { AggId: 'id; Created: DateTime; Payload: 'payload }
let mkEvent id created x = { AggId = id; Created = created; Payload = x }
let mkCmd id cmd = { AggId = id; Command = cmd }
type GameEventId = GameEventId
type TournamentId = TournamentId
type CategoryId = CategoryId
type MLString = { Ru: string; Uk: string; En: string }
type Limit =
| Amount of int
| Percent of int
| NoLimit
type Tournament = { Id: Guid; Name: MLString; }
type Category = { Id: Guid; Name: MLString; }
type P1P2 =
| P1 of float
| P2 of float
type Market =
| Win of P1P2
type TradingState = Open | Closed | Paused
type UserId = UserId of Guid
type Bet = { Player: UserId; Amount: float; Market: Market }
type MarketEvent =
| Added of Market
| Removed of Market
| Changed of Market
type Event =
| GameEventCreated of {| Name: MLString; Tournament: Tournament; Category: Category |}
| Market of MarketEvent
| LimitChanged of Limit
| TradingStateChanged of TradingState
| BetPlaced of Bet
type MarketName = MarketName of string
type Markets = Markets of Map<MarketName, Market>
let marketName = function
| Win _ -> MarketName "П1 - П2"
let marketsProj state events =
let folder (Markets state) event =
match event.Payload with
| Market (Added market) -> state |> Map.add (marketName market) market
| Market (Removed market) -> state |> Map.remove (marketName market)
| Market (Changed market) -> state |> Map.add (marketName market) market
| _ -> state
|> Markets
List.fold folder state events
let tradingStateProj state events =
let folder state event =
match event.Payload with
| TradingStateChanged ts -> ts
| _ -> state
List.fold folder state events
let bets state events =
let folder state event =
match event.Payload with
| BetPlaced bet -> bet::state
| _ -> state
List.fold folder state events
let sumOfBets state events =
bets [] events
|> List.sumBy ^ fun x -> x.Amount
|> fun sum -> state + sum
type IEventStore<'id, 'event> =
abstract Append : int64 -> EventMeta<'id, 'event> list -> Async<Result<int64, string>>
abstract GetFrom : int64 -> 'id -> Async<EventMeta<'id, 'event> list>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment