Algebrick¶ ↑
Typed structs on steroids based on algebraic types and pattern matching seamlessly integrating with standard Ruby features.
-
Documentation: blog.pitr.ch/algebrick
-
Source: github.com/pitr-ch/algebrick
Quick example¶ ↑
{include:file:doc/quick_example.out.rb}
Algebraic types¶ ↑
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 -
Leafwith and extra value of typeInt -
Nodewith 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 implementation¶ ↑
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.Listhas two variants:Emptyand 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 en.wikipedia.org/wiki/Algebraic_data_type.
Documentation¶ ↑
Type definition¶ ↑
{include:file:doc/type_def.out.rb}
Value creation¶ ↑
{include:file:doc/values.out.rb}
Behaviour extending¶ ↑
{include:file:doc/extending_behavior.out.rb}
Pattern matching¶ ↑
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}
Parametrized types¶ ↑
{include:file:doc/parametrized.out.rb}
What is it good for?¶ ↑
Defining data structures¶ ↑
-
Simple data structures like trees
-
Whenever you find yourself to pass around too many fragile Hash-Array structures
Examples are coming shortly.
Serialization¶ ↑
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}
Message matching in Actor pattern¶ ↑
Just a small snippet how it can be used in Actor model world.
{include:file:doc/actor.rb}