To be honest I wish I could have used yield
or return
but out of the options I had the others all seamed worse. i.e. else
and rescue
.
Well, you ācouldā. ^.^
OK.for do
a <- safe_div(8, 2)
b <- safe_div(a, 2)
yield a + b
end
Youād not be able to use a function named āyieldā though, but I think thatās fine.
Iād still just vote for:
OK.for do
a <- safe_div(8, 2)
b <- safe_div(a, 2)
a + b
end
It is perfectly and normally elixiry.
I certainly donāt disagree with you. Iām going to use it in some code and see how I feel about it. Iām also working on a writer monad for sending messages and am going to see how that looks with the separating after or not
I made a block syntax for monadāy style do expressions in expedeās exceptional
library as a PR if you want to see usage (though this one is for different style of error handling, the syntax is the same though): https://github.com/expede/exceptional/pull/18
Version 1.9.0 released with new OK.try
macro for normalising return values.
The syntax here is chosen to be basically the same as a natural try
block but in this case without any errors being raised.
Example
require OK
import Raxx
OK.try do
user <- fetch_user(1) # `<-` operator means func returns {:ok, user}
cart <- fetch_cart(1) # `<-` again, {:ok, cart}
order = checkout(cart, user) # `=` allows pattern matching on non-tagged funcs
saved_order <- save_order(order)
after
response(:created) # Value will be returned unwrapped
rescue
:user_not_found ->
response(:not_found)
:could_not_save ->
response(:internal_server_error)
end
This is a very nice way to write code that reliably returns the same type of value.
My favourite feature of this is it is familiar but raise
can now be used for exceptions that should never happen.
i.e. programmer errors that should end up in bug tracking software as soon as possible.
With OK.for
that was introduced in 1.8.0 I think that these are sane replacements for OK.with
which had variable behaviour dependant on which code blocks had been defined.
Version 1.9.1 released to fix warnings.
An warning that could occur when using pipes ~>>
has been rectified.
The following code now will not raise any errors.
{:ok, num}
~>> double()
Version 1.9.3 released to deprecate OK.with/1
The general purpose behaviour of OK.with
has been replaced with two separate options
-
OK.for
When a return value should be wrapped as an ok/error tuple -
OK.try
When error handling should be attempted, such as transforming errors to a 500 response.
See docs for details: https://hexdocs.pm/ok/1.9.3/readme.html
Version 1.10.0: Add map/2
and ~>
to treat result tuples as Functors.
The latest version of ok (1.10.0) has been release. It adds functionality to transform a value within an :ok
tuple. e.g.
Examples
iex> {:ok, 5} ~> Integer.to_string
{:ok, "5"}
iex> {:error, :zero_division_error} ~> Integer.to_string
{:error, :zero_division_error}
iex> {:ok, "a,b"} ~> String.split(",")
{:ok, ["a", "b"]}
Version 1.11.0 Add map_all/2
for working through lists.
Transform every element of a list with a mapping function.
The mapping function must return a result tuple.
If all of the result tuples are tagged :ok, then it returns a list tagged with :ok.
If one or more of the result tuples are tagged :error, it returns the first error.
Examples
iex> OK.map_all(1..3, &safe_div(6, &1))
{:ok, [6.0, 3.0, 2.0]}
iex> OK.map_all([-1, 0, 1], &safe_div(6, &1))
{:error, :zero_division}
OK 2.2.0 released
Added in 2.2
The functions OK.is_success?/1
and OK.is_failure?/1
.
Helpful when a series of checks only needs to return a boolean
Added in 2.1
The function OK.check/3
was added
https://hexdocs.pm/ok/2.2.0/OK.html#check/3
Use it to add extra validation to the value in an OK
User
|> Repo.get(user_id)
|> OK.check(fn () -> user.age > 10 end, :too_young_user)
Changed in 2.3
Deprecated OK.is_success?/1
and OK.is_failure?/1
in favor of OK.success?/1
and OK.failure?/1
.
Added OK.is_success/1
and OK.is_failure/1
guard macros.