Algebraic Data Types for Ruby.
Let's define a Shape data type:
require 'adts'
Shape = ADT do
Void() |
Square(width: Numeric) |
Rectangle(width: Numeric, height: Numeric) |
Circle(radius: Numeric) {
def area
Math::PI * radius * radius
end
}
end
Let's try to instantiate a Shape with our nullary constructor Void:
Shape::Void()
# => #<Shape::Void ...>
What about a square?
Shape::Square(23)
# => #<Shape::Square @width=23>
Our type constructors are even type-checked:
Shape::Square("foo")
# raises a TypeError
Our ADT implements equality by type and value:
Shape::Square(23) == Shape::Square(23)
# => true
Shape::Circle(23) == Shape::Square(23)
# => false
Shape::Square(23) == Shape::Square(99)
# => false
All its instances expose (read-only) their respective parameters:
Shape::Square(23).width
# => 23
All instances are a kind of Shape
:
Shape::Square(23).is_a?(Shape)
# => true
And finally, our constructors can have their own special methods, just like we
defined area
on Circle
:
Shape::Circle(1).area
# => 3.141592653589793
Add this line to your application's Gemfile:
gem 'adts'
And then execute:
$ bundle
Or install it yourself as:
$ gem install adts
This was made by Josep M. Bach (Txus) under the MIT license. I am @txustice on twitter (where you should probably follow me!).