peoj

peoj

Typespec for a type implementing behaviour

Let’s say I have a behaviour MyBehaviour and a function that may return any module implementing that behaviour. Is it possible to write a type spec for that?

For example (pseudo-code):

defmodule MyBehaviour do
  @callback say_hello() :: String.t()
end

defmodule MyBehaviourImplA do
  @behaviour MyBehaviour
  def say_hello(), do: "Hello from A"
end

defmodule MyBehaviourImplB do
  @behaviour MyBehaviour
  def say_hello(), do: "Hello from B"
end

defmodule ThisIsWhereTheQuestionComesIn do
  @spec get_module_implementing_behaviour() :: ?????
  def get_module_implementing_behaviour(), do: MyBehaviourImplA
end

I want to specify that ThisIsWhereTheQuestionComesIn.get_module_implementing_behaviour/0 could return either MyBehaviourImplA or MyBehaviourImplB (or indeed any module that implements that behaviour).

My use case is for a configurable adapter pattern; I want to write a function that returns whatever the currently configured adapter is.

Thanks as always!

Most Liked

oren1991

oren1991

I was looking for a similar solution, in the end I did something similar:

defmodule MyBehaviour do
  # Define a type for the behaviour
  @type t :: module()
  @callback say_hello() :: String.t()
end

defmodule MyBehaviourImplA do
  @behaviour MyBehaviour
  def say_hello(), do: "Hello from A"
end

defmodule MyBehaviourImplB do
  @behaviour MyBehaviour
  def say_hello(), do: "Hello from B"
end

defmodule ThisIsWhereTheQuestionComesIn do
  # Using the type of the behaviour module
  @spec get_module_implementing_behaviour() :: MyBehaviour.t
  def get_module_implementing_behaviour(), do: MyBehaviourImplA
end

Does not do much with the typechecks but maybe more readable than simple module or hardcode the exact module into the @spec :slight_smile:

10
Post #7
eksperimental

eksperimental

I think all you can do is:

@spec get_module_implementing_behaviour() :: module()

Where Next?

Popular in Questions Top

minhajuddin
I have seen a lot of code which picks the first element from a list using Enum.at(0) instead of List.first. Is there a reason why people ...
New
vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
openscript
Hello! Sorry for this astonishing simple question, but I’m really stuck. I try to set up the intellij-elixir plugin, but I don’t know ho...
New
komlanvi
Hi everyone, I was playing with phoenix liveView but I run into an issue. I have a form and want to validate each input text when the te...
New
bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
siddhant3030
Hi, I have to write a raw query for one of my project. But till now I have used ecto queries and don’t have much experience writing raw ...
New
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New

Other popular topics Top

ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
sen
Hi All, I set a environment variables in dev.exs , like below code. when i start server, how can i set the ${enable} value? thanks. d...
New
shijith.k
I am trying to start a new phoenix project with elixir 1.9, but mix phx.new does not work. It says that ** (Mix) The task "phx.new" could...
New
msaraiva
Surface is an experimental library built on top of Phoenix LiveView and its new LiveComponent API that aims to provide a more declarative...
564 44139 214
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID<0.412.0> terminating ** (Postgrex.Error) FATAL...
New
Harrisonl
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service. Currently when I de...
New

We're in Beta

About us Mission Statement