lessless
Is it possible to declare a generic type?
For example I have multiple currencies
dollar.ex
defmodule Multicurrency.Currency.Dollar do
@enforce_keys [:amount]
defstruct [:amount]
@type t :: %__MODULE__{
amount: integer()
}
@spec new(number()) :: Multicurrency.Currency.Dollar.t()
def new(amount) do
%__MODULE__{amount: amount}
end
end
franc.ex
defmodule Multicurrency.Currency.Franc do
@enforce_keys [:amount]
defstruct [:amount]
@type t :: %__MODULE__{
amount: integer()
}
@spec new(number()) :: Multicurrency.Currency.Franc.t()
def new(amount) do
%__MODULE__{amount: amount}
end
end
They are basically the same and I wonder if it’s possible to have some kind of a generic struct or a protocol for structs that will define common keys and allow to pattern match on the instances of that struct:
defmodule Multicurrency.Currency do
@enforce_keys [:amount]
defstruct [:amount]
@type t :: %__MODULE__{
amount: integer()
}
end
defmodule Multicurrency.Currency.Franc do
@impl Multicurrency.Currency
@spec new(number()) :: Multicurrency.Currency.t()
def new(amount) do
%__MODULE__{amount: amount}
end
end
def equals?(Multicurrency.Currency{amount: a1}, Multicurrency.Currency{amount: a2}) do
a1 == a2
end
Does it even make sense?
Most Liked
benwilson512
benwilson512
Right. This is readily apparent if two protocols both require a function called call/2 for example. If you implement this with monkey patching or even inheritance you’re gonna run into issues because the class can only have a single #call method. However you can easily create two different protocol implementations for two different protocols that both have a call function because you always pass the data structure to the protocol, so there’s no ambiguity.
blatyo
If you’re on the newest erlang you could do.
defguard is_currency(currency)
when :erlang.map_get(:__struct__, currency) in [Multicurrency.Currency.Franc, Multicurrency.Currency.Dollar]
def add(currency) when is_currency(currency) do
end
LostKobrakai
This should hopefully not be the message and I’d like to give some context. Many people question the elixir community whether or why there’s no static typing capabilities or at least something more rigorous than dialyzer, while being unaware that many people did work and are working in that space. But to my understanding there has not yet been found a good way to type the message passing capabilities for processes on the beam in a manner of favorable tradeoffs. There are also a few other less critical things to consider like e.g. hot code reloading.
Therefore it’s less a matter of not accepting or implementing feedback, but rather one of the community being aware of the requests and their benefits – but not having a solution – while the question of why this is not in elixir pops up regularly. There are many people who’d like to see more static typing in elixir and piece by piece the core team does seem to add the things to the compiler that they can.







