Reality check your library idea

I’ve started working on “sum type” package to scratch my own itch and would like to get some feedback on the API I’ve chosen. This is how you’d defined a sum type (often referred to as “union”).

For the example I’m gonna use the probably well known “Maybe” sum type:

defmodule Maybe do
  import ExUnion

  defunion some(value) | none
end

(I actually would’ve loved to do defunion Some(value) | None but that’s invalid Elixir syntax. :cry:)

To ease usage and integration into existing code-bases I’ve decided to transform this as much as possible into existing Elixir structures and patterns. So this snippet above would compile to:

defmodule Maybe do
  defmodule Some do
    @type t :: %__MODULE__{value: any}
    defstruct [:value]

    def new(value) do
      %__MODULE__{value: value}
    end
  end

  defmodule None do
    @type t :: %__MODULE__{}
    defstruct []

    def new() do
      %__MODULE__{}
    end
  end

  @type t :: Some.t() | None.t()
  
  defdelegate some(value),
    to: Some,
    as: :new

  defdelegate none(),
    to: None,
    as: :new

  defguard is_maybe(value) when is_struct(value, Some) or is_struct(value, None)
end

Usage then might look like this:

def some_function(maybe) when is_maybe(maybe) do
  case maybe do
    %Maybe.Some{value: value} ->
      # Do something with value

    %Maybe.None{} ->
      # Do something else
  end
end

Or building:

def returning_maybe(value) do
  case value do
    nil -> Maybe.none()
    non_nil -> Maybe.some(non_nil)
  end
end

Is there anything you’d be missing with this API? I’m also planning to support type annotations in the definition, so things like this would be possible:

defmodule Shape do
  import ExUnion

  defunion rectangle(height :: float, width :: float) | circle(radius :: float) | triangle(base :: float, height :: float)
end
1 Like

Would it be a good idea to sort of “translate” a REST request into a valid equivalent GraphQL mutation/query?

Does this exist already? Maybe a library/plug that’s able to translate/validate a REST JSON request? I’d be very interested in knowing if something like that exists already or if not, is it a good idea?