Erlang/Elixir Elixir 用 sum type 建模

chenge · May 09, 2021 · Last by linlinda replied at November 03, 2023 · 314 hits

昨天群里听网友介绍了这个 sum type 的博客,跟大家分享一下。

场景是设计一个双人比赛游戏,下面展示两种方案

原来的方案

defmodule Game do
  defstruct [:status, :players, :winning_player]

  @type status :: :not_started | :in_progress | :finished

  @type t :: %__MODULE__{
    status: status(),
    players: {Player.t(), Player.t()} | nil,
    winning_player: Player.t() | nil
  }
end

这个方案容易产生出现非法状态,导致 bug,接下来改进一下设计。

sum type 模式

defmodule Game do
  defstruct [:status]

  @type players :: {Player.t(), Player.t()}
  @type status :: :not_started | {:in_progress, players()} | {:finished, Player.t()}

  @type t :: %__MODULE__{status: status()}
end

更详细的内容,参考原来英文博客 Better domain modeling in Elixir with sum types

No Reply at the moment.
You need to Sign in before reply, if you don't have an account, please Sign up first.