Readable
Elixir language have standard String.Chars
protocol which describes T -> String
relation (like Haskell Show type class). But Elixir don't have any standard protocol for String -> T
relation (some equivalent of Haskell Read type class). But I think such protocol completely make sense.
This protocol describes read relation between 2 types. Instance of type B
can be read from instance of type A
. Usually type A = String
, but this implementation don't have this constraint.
Example
import Read
defreadable Integer, from: x :: BitString do
String.to_integer(x)
end
defreadable URI, from: x :: BitString do
URI.parse(x)
end
defreadable NaiveDateTime, from: x :: Tuple do
case NaiveDateTime.from_erl(x) do
{:ok, y} -> y
{:error, _} -> fail!(x)
end
end
and then we can use implementation of Read
type class
iex> Read.read("123", Integer)
123
iex> Read.read("https://hello.world", URI)
%URI{
authority: "hello.world",
fragment: nil,
host: "hello.world",
path: nil,
port: 443,
query: nil,
scheme: "https",
userinfo: nil
}
iex> Read.read({{2000, 1, 1}, {13, 30, 15}}, NaiveDateTime)
~N[2000-01-01 13:30:15]
iex> Read.read({{2000, 13, 1}, {13, 30, 15}}, NaiveDateTime)
** (Readable.Exception) NaiveDateTime can not be read from {{2000, 13, 1}, {13, 30, 15}}
iex> Read.read("https://hello.world", TypeNotExist)
** (ArgumentError) argument error
:erlang.binary_to_existing_atom("Elixir.Readable.From.BitString.To.TypeNotExist", :utf8)
(elixir) src/elixir_aliases.erl:119: :elixir_aliases.safe_concat/1
(readable) lib/read.ex:84: Read.read/2
Installation
The package can be installed by adding readable
to your list of dependencies in mix.exs
:
def deps do
[
{:readable, "~> 0.2"}
]
end