I believe these are referred to Railway-Oriented Programming. I've seen several other examples for Elixir (incl. ones using macros), but by far this is the 'cleanest' syntax :)
Here's a similar construct in Scala:
(for {
user <- currentUser(...)
group <- groups.fetchForUser(...)
friend <- friendships.fetchFriend(...)
member <- groups.addMember(...)
} yield {
render(...)
}).recover {
case e: Exception -> ...
}
The Scala example, yes... The Elixir one? Is it actually a Monad? I figure it's simply destructuring + pattern matching (against the value of the first tuple value, :ok or :error atom).
To expand a bit more, it's not like Scala's `Either[T, U]` where we're limited to a pair of types, I think you can return other atom values (but use :ok and :error) as a convention.
Also, there is an Elixir library I'm using that's a closer in spirit to Scala's for-comprehension called `monadex`. Example below:
result = success(comment_params)
~>> fn p -> link_reply_to_id(p) end
~>> fn p -> create_changeset(p) end
~>> fn cs -> assert_changeset(cs) end
~>> fn cs -> insert_changeset(cs) end
Here's a similar construct in Scala: