Я пытаюсь выяснить, как скомбинировать с параметризованными типами и переменными типа в спецификациях типа 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).
Есть ли способ, чтобы выразить это ограничение с помощью эликсира @spec
?