Elixir の型と関数の仕様でパラメーター化された型と型変数を組み合わせる方法を見つけようとしています。Stack
簡単な例として、モジュールを定義しているとしましょう:
defmodule Stack do
@type t :: t(any)
@type t(value) :: list(value)
@spec new() :: Stack.t
def new() do
[]
end
# What should the spec be?
def push(stack, item) do
[item|stack]
end
end
3 行目のパラメーター化された型仕様を使用して、整数のみを含む新しいスタックを作成する関数を定義できます。
@spec new_int_stack() :: Stack.t(integer)
def new_int_stack(), do: Stack.new
ここまでは順調ですね。ここで、整数のみをこのスタックにプッシュできるようにしたいと思います。たとえば、ダイアライザーはこれで問題ないはずです。
int_stack = new_int_stack()
Stack.push(int_stack, 42)
しかし、ダイアライザーはこれについて文句を言うべきです:
int_stack = new_int_stack()
Stack.push(int_stack, :boom)
push
それを強制するために関数の型仕様がどうあるべきかわかりません。Erlang では、次の構文でうまくいくと確信しています。
-spec push(Stack, Value) -> Stack when Stack :: Stack.t(Value).
Elixir を使用してこの制約を表現する方法はあり@spec
ますか?