Is there a better way to handle :ok tuples?

In my mind that is “sloppy typing” - always returning a two element tuple where the consistently typed value of the first element is an indication of the type of the second value is much cleaner - and I suspect much better for pattern matching.

The :ok/:error tuple is a poor man’s implementation of Either. When used correctly it makes it easier to compose functions without having to specify explicit conditionals to deal with the errors - i.e. it enables railway-oriented programming (ROP).

defmodule Demo  do

  def f1({hour, minute, second}),
    do: Time.new(hour, minute, second)

  def f2({:ok, time}),
    do: NaiveDateTime.new(Date.utc_today(), time)
  def f2(other),
    do: other

  def f3(input),
    do: input
        |> f1()
        |> f2()

end

IO.inspect(Demo.f3({3,2,0}))
IO.inspect(Demo.f3({25,2,0}))
$ elixir demo.exs
{:ok, ~N[2018-05-12 03:02:00]}
{:error, :invalid_time}

6 Likes