module Deterministic::Monad

Public Class Methods

new(init) click to toggle source

Basicly the ‘pure` function

# File lib/deterministic/monad.rb, line 6
def initialize(init)
  @value = join(init)
end

Public Instance Methods

'>>='(proc=nil, &block)
Alias for: bind
==(other) click to toggle source

Two monads are equivalent if they are of the same type and when their values are equal

# File lib/deterministic/monad.rb, line 66
def ==(other)
  return false unless other.is_a? self.class
  @value == other.instance_variable_get(:@value)
end
bind(proc=nil, &block) click to toggle source

The monad: takes a function which returns a monad (of the same type), applies the function

bind

(a -> Mb) -> M a -> M b

the self.class, i.e. the containing monad is passed as a second (optional) arg to the function

# File lib/deterministic/monad.rb, line 28
def bind(proc=nil, &block)
  (proc || block).call(value).tap do |result|

    # def parent_name(obj)
    #   parts = obj.class.name.split('::')
    #   if parts.count > 1
    #     parts[0..-2].join('::')
    #   else
    #     parts[0]
    #   end
    # end

    # self_parent  = parent_name(self)
    # other_parent = parent_name(result)
    # raise NotMonadError, "Expected #{result.inspect} to be an #{other_parent}" unless self_parent == other_parent

    parent = self.class.superclass === Object ? self.class : self.class.superclass
    raise NotMonadError, "Expected #{result.inspect} to be an #{parent}" unless result.is_a? parent
  end
end
Also aliased as: '>>='
fmap(proc=nil, &block) click to toggle source

The functor: takes a function (a -> b) and applies it to the inner value of the monad (Ma), boxes it back to the same monad (Mb)

fmap

(a -> b) -> M a -> M b

# File lib/deterministic/monad.rb, line 20
def fmap(proc=nil, &block)
  result = (proc || block).call(value)
  self.class.new(result)
end
inspect() click to toggle source
# File lib/deterministic/monad.rb, line 60
def inspect
  name = self.class.name.split("::")[-1]
  "#{name}(#{value})"
end
join(other) click to toggle source

If the passed value is monad already, get the value to avoid nesting M[M] is equivalent to M

# File lib/deterministic/monad.rb, line 12
def join(other)
  if other.is_a? self.class then other.value
  else other end
end
to_s() click to toggle source
# File lib/deterministic/monad.rb, line 56
def to_s
  value.to_s
end
value() click to toggle source

Get the underlying value, return in Haskell

return

M a -> a

# File lib/deterministic/monad.rb, line 52
def value
  @value
end