wolf4earth

wolf4earth

ExUnion - Tagged Unions for Elixir. Just that

ExUnion is meant to be a lightweight, elixir-y implementation of tagged unions (also called variant, discriminated union, sum type, etc.).

While conventionally Elixir tends to promote using tuples to model tagged unions - the {:ok, ...} | {:error, ...} pattern being a good example of that - this approach arguably lacks expressiveness, especially when modeling non-trivial unions. An alternative is to employ structs to model the individual cases of a tagged union, which works nicely but has the disadvantage of requiring significant boilerplate code.

ExUnion attempts to bridge this gap by generating the necessary boilerplate (and a bit more) through a concise albeit opinionated DSL. Below the following links you can see an example for an idea on how you might use ExUnion.

defmodule Maybe do
  import ExUnion

  defunion some(value) | none
end

iex> Maybe.none()
%Maybe.None{}

iex> Maybe.some("string!")
%Maybe.Some{value: "string!"}

# Requiring is necessary since `is_maybe` is a guard (defguard)
iex> require Maybe
iex> Maybe.is_maybe("What's the meaning of life, the universe, and everything?")
false
iex> Maybe.is_maybe(42)
false
iex> Maybe.is_maybe(Maybe.none())
true

For more examples take a look at the project’s README.

Most Liked

wolf4earth

wolf4earth

Not yet, it’s one of the things I’d like to explore, in addition to protocol derivation.

dimitarvp

dimitarvp

Pretty nice, I do like it.

Is the following usage considered asserting on information that’s an implementation detail? Or this is exactly how your library should be used when it comes to pattern matching?

def do_stuff_with(%Maybe.None{}), do: :dont_do_anything
def do_stuff_with(%Maybe.Some{...}), do: :do_the_thing
wolf4earth

wolf4earth

That’s exactly how it’s supposed to be used. It’s also why the generated code contains type specs to more readily reveal the underlying structure.

Guess I could be more explicit in the docs about that.

dimitarvp

dimitarvp

The docs are good, I am simply making sure because e.g. Ecto still has some structs whose fields are well-known but it’s still not recommended to rely on them always being there. Hence my question.

Thanks for clarifying. :+1:

IvanR

IvanR

Thanks for the splendid library! Now the choice types can be expressed even shorter than in F# (comparing to the examples from Domain Modeling Made Functional book by Scott Wlaschin).

Where Next?

Popular in Libraries Top

hpopp
After just over two years in development, this latest version of Pigeon is what I finally consider done in regards to my original vision ...
New
pkrawat1
Hey guyz We at @aviabird are working on a payment library in elixir/phoenix. We are targeting March 2018 to add 56 Gateways to it. Have...
New
Crowdhailer
Raxx is an alternative to Plug and is inspired by projects such as Rack(Ruby) and Ring(Clojure). 1.0-rc.1 is now available. To use it re...
New
KronicDeth
Elixir plugin for JetBrain’s IntelliJ Platform (including Rubymine) This is a plugin that adds support for Elixir to JetBrains IntelliJ...
289 35421 110
New
woutdp
Hi! I wanted to introduce my latest project LiveSvelte. It allows you to render Svelte inside LiveView with end-to-end reactivity. It’s ...
New
Qqwy
Solution is a library to help you with working with ok/error-tuples in case and with-expressions by exposing special matching macros, as ...
New
aditya7iyengar
Rummage.Ecto and Rummage.Phoenix provide ways to perform Searching, Sorting and Pagination over Ecto queries and Phoenix collections. Fo...
New
danschultzer
None of the current solutions worked well for me, so I went ahead and built a user management system from scratch. This project took far...
548 27727 240
New
mischov
import Meeseeks.CSS html = HTTPoison.get!("https://news.ycombinator.com/").body for story <- Meeseeks.all(html, css("tr.athing")) do...
New
New

Other popular topics Top

Tee
can someone please explain to me how Enum.reduce works with maps
New
pmjoe
I have a relationship of love and hate with Elixir. Lots of things are just absolutely right, but there are some things that are kind of ...
New
_russellb
I want to try my hand at web scraping. What tools/libraries do I need to use. I’m hoping to turn this into something professional so don’...
New
chensan
I have a User schema with a :from_id field set to type :string: defmodule TweetBot.Repo.Migrations.CreateUsers do use Ecto.Migration ...
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 42633 214
New
WestKeys
Currently suffering from paralysis by [HTTP client] analysis. This is rather unusual in Elixirland as there tends to be consensus on the ...
New
beno
I will often find my self writing things similar to: case some_value do nil -> something() "" -> something() _ -> someth...
New
josevalim
Hi everyone, One of the features added to Elixir early on to help integration with Erlang code was the idea of overridable function defi...
New
Nvim
Elixir appears to be a superior language to Python. I don’t see any advantage of Python over Elixir. Are there any?
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

Sub Categories:

We're in Beta

About us Mission Statement