ruby-monads
These are some Ruby implementations of some common monads.
Usage
If you don't already have it installed:
gem install ruby-monads
As these are just some new abstractions, just include it:
require "monads"
include Monads
Monads
Maybe
The maybe monad returns one of the following classes, wether it wraps a value or not:
Maybe.unit(42)
returns an instance ofJust
wrapping the42
valueMaybe.unit(nil)
returns an instance ofNothing
wrapping no value
Examples
Maybe.unit("Hello, World!") # => #<Monads::Just @value="Hello, World!">
Maybe.unit(nil) # => #<Monads::Nothing>
Maybe.unit("Hello, World!").upcase # => #<Monads::Just @value="HELLO, WORLD!">
Maybe.unit("Hello, World!").upcase.split.unwrap([]) # => ["HELLO,", "WORLD!"]
Maybe.unit("Hello, World!").bind { |v| Maybe.unit(nil) } # => #<Monads::Nothing>
Maybe.unit("Hello, World!").fmap { |v| v.gsub(/\w/, "*") } # => #<Monads::Just @value="*****, *****!">
Maybe.unit(Maybe.unit("Hello, World!")).join # => #<Monads::Just @value="Hello, World!">
Maybe.unit(nil).upcase # => #<Monads::Nothing>
Maybe.unit(nil).upcase.split.unwrap([]) # => []
Maybe.unit(nil).bind { |v| Maybe.unit("Hello, World!") } # => #<Monads::Maybe.unit(nil)>
Maybe.unit(nil).fmap { |v| v.gsub(/\w/, "*") } # => #<Monads::Nothing>
Maybe.unit(Maybe.unit(nil)).join # => #<Monads::Nothing>
Result
The result monad returns one of the following classes, wether it wraps an error or not:
Result.unit(42)
returns an instance ofSuccess
wrapping the42
valueResult.unit(StandardError.new)
returns an instance ofFailure
wrapping the given error
Examples
Result.unit("Hello, World!") # => #<Monads::Success @value="Hello, World!">
Result.unit(StandardError.new("Wrong!")) # => #<Monads::Failure @value=#<StandardError: Wrong!>>
Result
.unit("Hello, World!") # => #<Monads::Success @value="Hello, World!">
.upcase # => #<Monads::Success @value="HELLO, WORLD!">
.even # => #<Monads::Failure @value=#<NoMethodError: undefined method `even?' for "HELLO, WORLD!":String>>
.split # => #<Monads::Failure @value=#<NoMethodError: undefined method `even?' for "HELLO, WORLD!":String>>
.unwrap("default") # "default"
Why this gem
This gem is heavily inspired by the following monads implementations:
These gems, and many others are really great, and it was very instructive to learn about this topic in my beloved language. However, after reading a lot of implementations and articles, I had a clear opinion of how I wanted it:
- Minimalist: as simple an lightweight as possible
- Respectful of uses: respectful of the usual terms (Monad (functional programming)), like
Maybe
,unit
,bind
,join
, etc. - Vanilla Ruby syntax: I love some of the abstractions I discovered (
>=
operator,Just(value)
syntax). However, I also love vanilla Ruby. So, I wanted to target new methods and abstractions, not new syntaxes comming from other languages.
Tests
Test suite uses cutest. You can execute it with:
make