Typed structs on steroids based on algebraic types and pattern matching seamlessly integrating with standard Ruby features.
- Documentation: http://blog.pitr.ch/algebrick
- Source: https://github.com/pitr-ch/algebrick
- Blog: http://blog.pitr.ch/blog/categories/algebrick/
{include:file:doc/quick_example.out.rb}
Algebraic types are:
- products with a given number of fields,
- or a kind of composite type, i.e. a type formed by combining other types.
In Haskell algebraic type looks like this:
data Tree = Empty
| Leaf Int
| Node Tree Tree
depth :: Tree -> Int
depth Empty = 0
depth (Leaf n) = 1
depth (Node l r) = 1 + max (depth l) (depth r)
depth (Node Empty (Leaf 5)) -- => 2
This snippet defines type Tree
which has 3 possible values:
Empty
Leaf
with and extra value of typeInt
Node
with two values of typeTree
and function depth
to calculate depth of a tree which is called on the last line and evaluates to 2
.
Same Tree
type and depth
method can be also defined with this gem as it was shown in {file:README_FULL.md#quick-example Quick Example}.
Algebrick distinguishes 4 kinds of algebraic types:
- Atom - type that has only one value, e.g.
Empty
. - Product - type that has a set number of fields with given type, e.g.
Leaf(Integer)
- Variant - type that is one of the set variants, e.g.
Tree(Empty | Leaf(Integer) | Node(Tree, Tree)
, meaning that valuesEmpty
,Leaf[1]
,Node[Empty, Empry]
have all typeTree
. - ProductVariant - will be created when a recursive type like
List(Empty | List(Integer, List))
is defined.List
has two variants:Empty
and itself. Simultaneously it has fields as a product type.
Atom type is implemented with {Algebrick::Atom} and the rest is implemented with {Algebrick::ProductVariant} which behaves differently based on what is set: fields, variants, or both.
More information can be found at https://en.wikipedia.org/wiki/Algebraic_data_type.
{include:file:doc/type_def.out.rb}
{include:file:doc/values.out.rb}
{include:file:doc/extending_behavior.out.rb}
Pattern matching is implemented with helper objects defined in ALgebrick::Matchers
.
They use standard #===
method to match against values.
{include:file:doc/pattern_matching.out.rb}
{include:file:doc/parametrized.out.rb}
- Simple data structures like trees
- Whenever you find yourself to pass around too many fragile Hash-Array structures
Examples are coming shortly.
Algebraic types also play nice with JSON serialization and de-serialization making it ideal for defining message-based cross-process communication.
{include:file:doc/json.out.rb}
Just a small snippet how it can be used in Actor model world.
{include:file:doc/actor.rb}