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}