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?
First Post!
OvermindDL1
You can with the built-in Protocol if you handle all currency types within your singular protocol implementation or double-dispatch out to another protocol for the specific currency type (which should be fine).
If you truly want to protocol dispatch over an instance binding (I.E. full match) then the built-in Protocol cannot do that but ProtocolEx can (and it can be faster than Elixir protocols as well). But I don’t recommend it until you actually Need proper match semantics.
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
Last Post!
lessless
Nope, things like this are pretty much still impossible according to my understanding Rust Playground
I’m talking about line 14 - fn print_quantity(order: OrderQuantity). It’s possible to give design a different spin, but sometimes it can mean twisting abstractions to match tool’s abilities.
The closest answer was provided by blatyi Is it possible to declare a generic type? - #10 by blatyo
I’ve read on Twitter that folks at WhatsApp might be working on something up that avenue. Maybe @michalmuskala can enlight us or shed the gossip hehe ![]()
Trending in Questions
Other Trending Topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #elixirconf-us
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #metaprogramming
- #security
- #hex









