Skip to content

Latest commit

 

History

History
113 lines (66 loc) · 3.4 KB

README_FULL.md

File metadata and controls

113 lines (66 loc) · 3.4 KB

Algebrick

Typed structs on steroids based on algebraic types and pattern matching seamlessly integrating with standard Ruby features.

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
  • Leaf with and extra value of type Int
  • Node with two values of type Tree

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:

  1. Atom - type that has only one value, e.g. Empty.
  2. Product - type that has a set number of fields with given type, e.g. Leaf(Integer)
  3. Variant - type that is one of the set variants, e.g. Tree(Empty | Leaf(Integer) | Node(Tree, Tree), meaning that values Empty, Leaf[1], Node[Empty, Empry] have all type Tree.
  4. 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.

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}