I searched everywhere for this but couldn’t quite find what I’m looking for, which is a way to reference a function’s return type in another function’s @spec. Allow me to demonstrate:
Below is a representation of what I’d like to do: to capture the fun type’s return_type property (which I wrote as return_type for this example)
defmodule MyStruct do
defstruct [:data]
@type t(member) :: %__MODULE__{
data: [member]
}
end
defmodule MyFunctions do
@spec transform(list, fun) :: MyStruct.t(fun.return_type)
def transform(raw_content, map_fn), do: %MyStruct{data: Enum.map(raw_content, map_fn)}
end
The snippet above would state that the return type of transform is a %MyStruct{} struct whose data field’s type is an array produced by the output of the second argument, map_fn.
Although I can solve this by using the struct() type instead of fun.return_type, I’d like to be as precise as possible with these types.
I ended up using a simple struct as the typespec. My main wish was to have a generic statement to save me from having to add function guards for each type supported by that function. If they were two or three, it would be ok, but for a dozen types I’d be writing spaghetti guard statements.
Nonetheless, I made some elegant changes by plugging guards into the code. Thank you again!