Module: Deterministic::Monad

Included in:
Either, EnumBuilder::DataType::AnyEnum
Defined in:
lib/deterministic/monad.rb

Defined Under Namespace

Classes: NotMonadError

Instance Method Summary collapse

Instance Method Details

#==(other) ⇒ Object

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



66
67
68
69
# 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) ⇒ Object Also known as: >>=

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



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# 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

#fmap(proc = nil, &block) ⇒ Object

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



20
21
22
23
# File 'lib/deterministic/monad.rb', line 20

def fmap(proc=nil, &block)
  result = (proc || block).call(value)
  self.class.new(result)
end

#initialize(init) ⇒ Object

Basicly the ‘pure` function



6
7
8
# File 'lib/deterministic/monad.rb', line 6

def initialize(init)
  @value = join(init)
end

#inspectObject

Return the string representation of the Monad



72
73
74
75
# File 'lib/deterministic/monad.rb', line 72

def inspect
  name = self.class.name.split("::")[-1]
  "#{name}(#{value})"
end

#join(other) ⇒ Object

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



12
13
14
15
# File 'lib/deterministic/monad.rb', line 12

def join(other)
  if other.is_a? self.class then other.value
  else other end
end

#to_sObject



56
57
58
# File 'lib/deterministic/monad.rb', line 56

def to_s
  value.to_s
end

#valueObject

Get the underlying value, return in Haskell

return

M a -> a



52
53
54
# File 'lib/deterministic/monad.rb', line 52

def value
  @value
end