【问题标题】:Elixir: how to make a custom type implement ==, <, and >Elixir:如何使自定义类型实现 ==、< 和 >
【发布时间】:2020-01-02 13:47:11
【问题描述】:

背景:我正在努力将这个 F# 可区分联合转换为 Elixir:

type Suit =
| Diamonds
| Clubs
| Hearts
| Spades

我知道有几种不同的方法可以做到这一点,这不是我的问题。

以下必须为真:

Diamonds == Diamonds
Diamonds < Hearts
Spades > Hearts

我惊讶地发现 Elixir 没有与 Haskell 的 Ord 类型类和 GitHub 上的 implementation 类似的协议(星星很少!)

是否有一种被广泛接受或惯用的方法来使自定义类型具有可比性?

【问题讨论】:

    标签: functional-programming elixir


    【解决方案1】:

    执行此操作的惯用方法是在定义自定义类型的模块中简单地提供equal?/2 和/或compare/2。这可以在核心库和健壮的第三方库中经常看到。

    例如,Date.compare/2 具有以下规范

    compare(Calendar.date(), Calendar.date()) :: :lt | :eq | :gt
    

    v1.10.0 开始,Elixir 为实现compare/2 的结构提供了方便的Enum.sort/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"}]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-11-11
      • 1970-01-01
      • 1970-01-01
      • 2018-09-06
      • 1970-01-01
      • 1970-01-01
      • 2020-05-15
      • 2010-12-03
      相关资源
      最近更新 更多