Erlang
Elixir
dialyzer

Elixirの静的型チェックの確認 - リテラル型

結論。
Elixirの静的型チェックで、文字列を指定してすることはできない。
長さぐらいは可能。
同様のことをしたいならatomを使う。
ちゃんと確認してないが、Erlangでも同じだろう。

具体的に

便宜上Flowと比較する。

Flowで以下のような型をElixirで表現するにはどうするか。

// @flow
function sample(hoge_or_goro: "hoge" | "goro") {}

sample("hoge")    // Ok
sample("hogehoge") // Error
sample("goro")    // Ok

関数sampleは "hoge""goro"という値しか受け取らないようにしたい。

Elixirでは以下のようにするのが良さそう

defmodule Sample do
  @spec sample(:hoge | :goro) :: nil
  def sample(hoge_or_goro), do: nil

  def test(:hoge), do: nil  # Ok
  def test2(:hogehoge), do: nil # Error
  def test3(:goro), do: nil # Ok
  def test4(:mogu), do: nil # Error
end

bitstringを使う場合はせいぜい長さを指定するぐらいはできる

defmodule Sample do
  @spec sample(<<_::32>) :: nil
  def sample(hoge_or_goro), do: nil

  def test("hoge"), do: nil  # Ok
  def test2("hogehoge"), do: nil # Error
  def test3("goro"), do: nil # Ok
  def test4("mogu"), do: nil # Ok (Errorにしたい)
end

@spec sample(<<"hoge"::32>> :: nilみたいにかきたいがコンパイルできない。

数値リテラル

数値は可能。
まずは、Flowの場合の例

// @flow
function sample(one_or_three: 1 | 3) {}

sample(1) // Ok
sample(2) // Error
sample(3) // Ok
sample(1+2) // Error (Okにしたくはある)
defmodule Sample do
  @spec sample(1 | 3) :: nil
  def sample(one_or_three), do: nil

  def test(), do: hoge(1)  # Ok
  def test2(), do: hoge(2) # Error
  def test3(), do: hoge(3) # Ok
  def test4(), do: hoge(1+2) # Ok (やったぜ)
end

参考