Ok Jose
A tiny library for piping function return
values on a given pattern like the erlang
idiom {:ok, _} and {:error, _} tuples.
You can also define your own pattern-matched
pipes besides ok and error.
Also, checkout happy
Installation
- Add ok_jose to your list of dependencies in
mix.exs:
def deps do
[{:ok_jose, "~> 2.0.0"}]
endMotivation
A lot of erlang libraries follow the
convention of returning {:ok, _} and
{:error, _} tuples to denote success or failure.
This library is my try at having a beautiful syntax for a happy pipe, that is, a pipe that expects {:ok, _} tuples to be returned by each piped function.
If any piped function returns a non matched value, the remaining functions expecting an {:ok, _} value wont get executed.
So, for example, the following code
filename
|> File.read()
|> case do
{:ok, content} ->
content |> Poison.Parser.parse()
{:error, _} = error -> error
endcan be written as:
filename |> File.read |> Poison.Parser.parse |> okor alternatively:
ok(filename |> File.read |> Poison.Parser.parse)Usage
use OkJoseProvides you with the following macros:
ok, ok!, error, error!
use OkJose.Pipewhich provides you the defpipe macro.
ok/1
Pipes values into functions as long as they match {:ok, _}
{:ok, v} |> f |> g |> okok!/1
Pipes values into functions but if at any point a value
does not match {:ok, _} raises a match error.
defpipe
Allows you to define custom pipe patterns, for example
the previous ok!, macro is defined like:
defpipe ok! do
{:ok, value} -> value
endThe do block of defpipe has the same form as the elixir case expression.
So for example, you may define a pipe to work on kittens only:
defpipe purr do
c = %Kitten{} -> c
t = %Tiger{domesticated: true} -> t
endExample
ok math
def dup(x), do: {:ok, x * 2}
def nop(x), do: {:error, x}
{:ok, 12} |> dup |> dup |> ok # => {:ok, 48}
{:ok, 24} |> nop |> dup |> ok # => {:error, 24}
{:ok, 24} |> dup |> ok! # => 48
{:ok, 24} |> nop |> dup |> ok! # raiseskittens
defpipe ok_kitten do
k = %Kitten{} -> k
t = %Tiger{domesticated: true} -> t
end
def purr(%Kitten{}), do: "purr"
def purr(%Tiger{}), do: "PuRRR"
%Kitten{} |> purr |> ok_kitten #=> "purr"
ok_kitten( %Doggie{} |> purr ) #=> %Doggie{}
# using do/end syntax
# block executed only for matching kittens
%Kitten{} |> (ok_kitten do
k -> purr(k)
end)About ok
I wanted name this library ok, but the hex
package name was already taken. So I just wanted to make a
tribute to @josevalim.
Actually both projects are trying to solve the
same issue. But I think this one has an easier
syntax that consist of just piping to ok
Also, checkout happy
Is it any good?
マクロス Makurosu
[Elixir macros,] The things I do for beautiful code ― George Martin, Game of Thrones