Set*_*eth 3 functional-programming elixir
背景:我正在将这个 F# 可区分联合转换为 Elixir:
type Suit =
| Diamonds
| Clubs
| Hearts
| Spades
Run Code Online (Sandbox Code Playgroud)
我知道有几种不同的方法可以做到这一点,这不是我的问题。
以下必须为真:
Diamonds == Diamonds
Diamonds < Hearts
Spades > Hearts
Run Code Online (Sandbox Code Playgroud)
我很惊讶地发现 Elixir 没有类似于 Haskell 的Ord类型类的类似协议和GitHub 上的这个实现(很少有星星!)
是否有一种广为接受或惯用的方法来使自定义类型具有可比性?
这样做的惯用方法是简单地提供equal?/2和/或compare/2在定义自定义类型的模块中。这可以在核心库和强大的第三方库中经常看到。
例如,Date.compare/2具有以下规格
compare(Calendar.date(), Calendar.date()) :: :lt | :eq | :gt
Run Code Online (Sandbox Code Playgroud)
从 开始v1.10.0,Elixir为Enum.sort/2实现 的结构提供了方便的排序compare/2:
defmodule User do
defstruct [:name]
def compare(%User{name: n1}, %User{name: n2}) when n1 < n2,
do: :lt
def compare(%User{name: n1}, %User{name: n2}) when n1 > n2,
do: :gt
def compare(%User{}, %User{}), do: :eq
end
users = [
%User{name: "john"},
%User{name: "joe"},
%User{name: "jane"}
]
Enum.sort(users, {:asc, User})
#? [%User{name: "jane"},
# %User{name: "joe"},
# %User{name: "john"}]
Run Code Online (Sandbox Code Playgroud)