Realm v0.1.0 Realm View Source

A set of functions to mimic the standard Haskell libraries feature a number of type classes with algebraic or category-theoretic underpinnings. The functions in this module come in two flavors: named or operators. For example:

iex> use Realm
iex> append(1, 1) # named
2
iex> 1 <> 1 # operator
2

If you prefer to use only operators or skip them, you can pass the following options:

  • :only_operators - includes only operators
  • :skip_operators - skips operators For example: iex> use Realm, onlyoperators: true iex> 1 <> 1 2 When invoked with no options, use Realm is equivalent to import Realm. All bitwise functions can be used in guards: iex> appendable? = fn ...> semigroup when Realm.append(semigroup, 1) == 2 -> true ...> -> false ...> end iex> appendable?.(1) true

Link to this section Summary

Functions

The opposite of equivalent?/2.

Duplicate incoming data into both halves of a 2-tuple, and run one function on the left copy, and a different function on the right copy.

Determine if an element is :lesser than another.

Same as ap/2, but with all functions curried.

Determine if an element is :lesser or :equal to another.

There is an operator alias a <> b. Since this conflicts with Kernel.<>/2, use Realm,Semigroup will automatically exclude the Kernel operator. This is highly recommended, since <> behaves the same on bitstrings, but is now available on more datatypes.

Composition operator "the math way". Alias for compose/2.

lift/2 but with arguments flipped.

Composition operator "the pipe way". Alias for compose/2.

Determine if an element is equal to another.

Determine if an element is :greater than another.

Determine if an element is :greater or :equal to another.

Take two arguments (as a 2-tuple), and run one function on the left side (first element), and run a different function on the right side (second element).

There is an operator alias a <> b. Since this conflicts with Kernel.<>/2, use Realm,Semigroup will automatically exclude the Kernel operator. This is highly recommended, since <> behaves the same on bitstrings, but is now available on more datatypes.

Determine if an element is :greater or :equal to another.

Determine if an element is :lesser or :equal to another.

Composition operator "the math way". Alias for compose/2.

Determine if an element is equal to another.

Duplicate incoming data into both halves of a 2-tuple, and run one function on the left copy, and a different function on the right copy.

Composition operator "the pipe way". Alias for compose/2.

Determine if an element is :greater than another.

Determine if an element is :lesser than another.

map/2 but with the function automatically curried

The opposite of equivalent?/2.

lift/2 but with arguments flipped.

Take two arguments (as a 2-tuple), and run one function on the left side (first element), and run a different function on the right side (second element).

Same as ap/2, but with all functions curried.

Same as convey/2, but with all functions curried.

map/2 but with the function automatically curried

Same as convey/2, but with all functions curried.

Link to this section Functions

The opposite of equivalent?/2.

Examples

iex> 1 != 2
true

Duplicate incoming data into both halves of a 2-tuple, and run one function on the left copy, and a different function on the right copy.

         ------> f.(a) = x ------
         |                        v
a ---> split = {a, a}           {x, y}
         |                        ^
         ------> g.(a) = y ------

Examples

iex> fanned = fn x -> x - 10 end &&& fn y -> inspect(y) <> "!" end
...> fanned.(42)
{32, "42!"}
iex> fanned =
...>   fn x -> x - 10 end
...>   &&& fn y -> inspect(y) <> "!" end
...>   &&& fn z -> inspect(z) <> "?" end
...>   &&& fn d -> inspect(d) <> inspect(d) end
...>   &&& fn e -> e / 2 end
...>
...> fanned.(42)
{{{{32, "42!"}, "42?"}, "4242"}, 21.0}

Determine if an element is :lesser than another.

Examples

iex> 1 < 1
false
iex> 1 < 1.1
true

Same as ap/2, but with all functions curried.

Examples

iex> [fn x -> x + 1 end, fn y -> y * 10 end] <<~ [1, 2, 3]
[2, 3, 4, 10, 20, 30]
iex> import Realm.Functor
...>
...> [100, 200]
...> ~> fn(x, y, z) -> x * y / z
...> end <<~ [5, 2]
...>     <<~ [100, 50]
...> ~> fn x -> x + 1 end
[6.0, 11.0, 3.0, 5.0, 11.0, 21.0, 5.0, 9.0]
iex> import Realm.Functor, only: [<~: 2]
...> fn(a, b, c, d) -> a * b - c + d end <~ [1, 2] <<~ [3, 4] <<~ [5, 6] <<~ [7, 8]
[5, 6, 4, 5, 6, 7, 5, 6, 8, 9, 7, 8, 10, 11, 9, 10]

Determine if an element is :lesser or :equal to another.

Examples

iex> use Realm.Ord
...> 1 <= 2
true
...> [] <= [1, 2, 3]
false
...> [1] <= [1, 2, 3]
true
...> [4] <= [1, 2, 3]
false

There is an operator alias a <> b. Since this conflicts with Kernel.<>/2, use Realm,Semigroup will automatically exclude the Kernel operator. This is highly recommended, since <> behaves the same on bitstrings, but is now available on more datatypes.

Examples

iex> use Realm.Semigroup
...> 1 <> 2 <> 3 <> 5 <> 7
18
iex> use Realm.Semigroup
...> [1, 2, 3] <> [4, 5, 6] <> [7, 8, 9]
[1, 2, 3, 4, 5, 6, 7, 8, 9]
iex> use Realm.Semigroup
...> "foo" <> " " <> "bar"
"foo bar"

Composition operator "the math way". Alias for compose/2.

Examples

iex> times_ten_plus_one =
...>       fn x -> x + 1  end
...>   <|> fn y -> y * 10 end
...>
...> times_ten_plus_one.(5)
51

lift/2 but with arguments flipped.

iex> (fn x -> x + 5 end) <~ [1,2,3]
[6, 7, 8]

Note that the mnemonic is flipped from |>, and combinging directions can be confusing. It's generally recommended to use ~>, or to keep <~ on the same line both of it's arguments:

iex> fn(x, y) -> x + y end <~ [1, 2, 3]
...> |> List.first()
...> |> apply([9])
10

...or in an expression that's only pointing left:

iex> fn y -> y * 10 end
...> <~ fn x -> x + 55 end
...> <~ [1, 2, 3]
[560, 570, 580]

Composition operator "the pipe way". Alias for compose/2.

Examples

iex> times_ten_plus_one =
...>       fn y -> y * 10 end
...>   <~> fn x -> x + 1  end
...>
...> times_ten_plus_one.(5)
51

Determine if an element is equal to another.

Examples

iex> use Realm.Ord
...> 2 == 1
false
...> 1 == 1
true

Determine if an element is :greater than another.

Examples

iex> 1 > 1
false
iex> 1.1 > 1
true

Determine if an element is :greater or :equal to another.

Examples

iex> use Realm.Ord
...> at_least?(2,  1)
true
...> at_least?([1, 2, 3], [])
true
...> at_least?([1, 2, 3], [1])
true
...> at_least?([1, 2, 3], [4])
false

Take two arguments (as a 2-tuple), and run one function on the left side (first element), and run a different function on the right side (second element).

  ------> f.(a) = x -------
  |                         v
{a, b}                    {x, y}
  |                         ^
  ------> g.(b) = y -------

Examples

iex> arr = fn x -> x - 10 end ^^^ fn y -> y <> "!" end
...> arr.({42, "Hi"})
{32, "Hi!"}
iex> {42, "Hi"} |> (fn x -> x - 10 end ^^^ fn y -> y <> "!" end).()
{32, "Hi!"}

There is an operator alias a <> b. Since this conflicts with Kernel.<>/2, use Realm,Semigroup will automatically exclude the Kernel operator. This is highly recommended, since <> behaves the same on bitstrings, but is now available on more datatypes.

Examples

iex> use Realm.Semigroup
...> 1 <> 2 <> 3 <> 5 <> 7
18
iex> use Realm.Semigroup
...> append([1, 2, 3], [4, 5, 6]) |> append([7, 8, 9])
[1, 2, 3, 4, 5, 6, 7, 8, 9]
iex> use Realm.Semigroup
...> append("foo", " ") |> append("bar")
"foo bar"
Link to this function

at_least?(left, right)

View Source
at_least?(Realm.Ord.t(), Realm.Ord.t()) :: boolean()

Determine if an element is :greater or :equal to another.

Examples

iex> use Realm.Ord
...> 2 >= 1
true
...> [1, 2, 3] >= []
true
...> [1, 2, 3] >= [1]
true
...> [1, 2, 3] >= [4]
false
Link to this function

at_most?(left, right)

View Source
at_most?(Realm.Ord.t(), Realm.Ord.t()) :: boolean()

Determine if an element is :lesser or :equal to another.

Examples

iex> use Realm.Ord
...> at_most?(1, 2)
true
...> at_most?([], [1, 2, 3])
false
...> at_most?([1], [1, 2, 3])
true
...> at_most?([4], [1, 2, 3])
false

Composition operator "the math way". Alias for compose/2.

Examples

iex> times_ten_plus_one = compose(fn x -> x + 1  end, fn y -> y * 10 end)
...>
...> times_ten_plus_one.(5)
51

Determine if an element is equal to another.

Examples

iex> use Realm.Ord
...> equal?(2, 1)
false
...> equal?(1, 1)
true

Duplicate incoming data into both halves of a 2-tuple, and run one function on the left copy, and a different function on the right copy.

         ------> f.(a) = x ------
         |                        v
a ---> split = {a, a}           {x, y}
         |                        ^
         ------> g.(a) = y ------

Examples

iex> fanned = fn x -> x - 10 end &&& fn y -> inspect(y) <> "!" end
...> fanned.(42)
{32, "42!"}
iex> fanned =
...>   fanout(fn x -> x - 10 end, fn y -> inspect(y) <> "!" end)
...>   |> fanout(fn z -> inspect(z) <> "?" end)
...>   |> fanout(fn d -> inspect(d) <> inspect(d) end)
...>   |> fanout(fn e -> e / 2 end)
...>
...> fanned.(42)
{{{{32, "42!"}, "42?"}, "4242"}, 21.0}

Composition operator "the pipe way". Alias for compose/2.

Examples

iex> times_ten_plus_one = flow_compose(fn y -> y * 10 end, fn x -> x + 1  end)
...>
...> times_ten_plus_one.(5)
51
Link to this function

greater?(left, right)

View Source
greater?(Realm.Ord.t(), Realm.Ord.t()) :: boolean()

Determine if an element is :greater than another.

Examples

iex> greater?(1, 1)
false
iex> greater?(1.1, 1)
true

Determine if an element is :lesser than another.

Examples

iex> lesser?(1, 1)
false
iex> lesser?(1, 1.1)
true
Link to this function

lift(functor, fun)

View Source
lift(Realm.Functor.t(), (... -> any())) :: Realm.Functor.t()

map/2 but with the function automatically curried

Examples

iex> lift([1, 2, 3], fn x -> x + 55 end)
...> |> lift(fn y -> y * 10 end)
[560, 570, 580]
iex> lift([1, 2, 3], fn(x, y) -> x + y end)
...> |> List.first()
...> |> apply([9])
10
Link to this function

nonequivalent?(left, right)

View Source
nonequivalent?(Realm.Setoid.t(), Realm.Setoid.t()) :: boolean()

The opposite of equivalent?/2.

Examples

iex> nonequivalent?(1, 2)
true
Link to this function

over(fun, functor)

View Source
over((... -> any()), Realm.Functor.t()) :: Realm.Functor.t()

lift/2 but with arguments flipped.

iex> lift(fn x -> x + 5 end, [1,2,3])
[6, 7, 8]

Note that the mnemonic is flipped from |>, and combinging directions can be confusing. It's generally recommended to use ~>, or to keep <~ on the same line both of it's arguments:

iex> over(fn(x, y) -> x + y end, [1, 2, 3])
...> |> List.first()
...> |> apply([9])
10

...or in an expression that's only pointing left:

iex> over(fn y -> y * 10 end, fn x -> x + 55 end)
...> |> over([1, 2, 3])
[560, 570, 580]

Take two arguments (as a 2-tuple), and run one function on the left side (first element), and run a different function on the right side (second element).

  ------> f.(a) = x -------
  |                         v
{a, b}                    {x, y}
  |                         ^
  ------> g.(b) = y -------

Examples

iex> arr = product(fn x -> x - 10 end, fn y -> y <> "!" end)
...> arr.({42, "Hi"})
{32, "Hi!"}
iex> {42, "Hi"} |> product(fn x -> x - 10 end, fn y -> y <> "!" end).()
{32, "Hi!"}

Same as ap/2, but with all functions curried.

Examples

iex> [fn x -> x + 1 end, fn y -> y * 10 end] <<~ [1, 2, 3]
[2, 3, 4, 10, 20, 30]
iex> import Realm.Functor
...>
...> [100, 200]
...> ~> fn(x, y, z) -> x * y / z end
...> |> provide([5, 2])
...> |> provide([100, 50])
...> |> provide(fn x -> x + 1 end)
[6.0, 11.0, 3.0, 5.0, 11.0, 21.0, 5.0, 9.0]
iex> import Realm.Functor, only: [<~: 2]
...> fn(a, b, c, d) -> a * b - c + d end <~ [1, 2] |> provide([3, 4]) |> provide([5, 6]) |> provide([7, 8])
[5, 6, 4, 5, 6, 7, 5, 6, 8, 9, 7, 8, 10, 11, 9, 10]

Same as convey/2, but with all functions curried.

Examples

iex> [1, 2, 3] ~>> [fn x -> x + 1 end, fn y -> y * 10 end]
[2, 10, 3, 20, 4, 30]
iex> import Realm.Functor
...>
...> [100, 50]
...> |> supply([5, 2]     # Note the bracket
...> |> supply([100, 200] # on both `Apply` lines
...> ~> fn(x, y, z) -> x * y / z end))
[5.0, 10.0, 2.0, 4.0, 10.0, 20.0, 4.0, 8.0]

map/2 but with the function automatically curried

Examples

iex> [1, 2, 3]
...> ~> fn x -> x + 55 end
...> ~> fn y -> y * 10 end
[560, 570, 580]
iex> [1, 2, 3]
...> ~> fn(x, y) -> x + y end
...> |> List.first()
...> |> apply([9])
10

Same as convey/2, but with all functions curried.

Examples

iex> [1, 2, 3] ~>> [fn x -> x + 1 end, fn y -> y * 10 end]
[2, 10, 3, 20, 4, 30]
iex> import Realm.Functor
...>
...> [100, 50]
...> ~>> ([5, 2]     # Note the bracket
...> ~>> ([100, 200] # on both `Apply` lines
...> ~> fn(x, y, z) -> x * y / z end))
[5.0, 10.0, 2.0, 4.0, 10.0, 20.0, 4.0, 8.0]