Module: Obfusk::Monad::ClassMethods

Defined in:
lib/obfusk/monad.rb

Instance Method Summary collapse

Instance Method Details

#bind(m, k = nil, &b) ⇒ Object

sequentially compose two actions; passing any value produced by the first as an argument to the second when a block is used; discarding any value produced by the first when no block is used; see bind_pass, bind_discard

bind(m) { |x| k } # pass value
bind m, k         # discard value


42
43
44
45
# File 'lib/obfusk/monad.rb', line 42

def bind(m, k = nil, &b)
  b ? bind_pass(m, &b) : k.is_a?(::Proc) ? bind_pass(m, &k) :
                                           bind_discard(m, k)
end

#bind_discard(m, k) ⇒ Object

sequentially compose two actions, discarding any value produced by the first

implement me!



59
60
61
# File 'lib/obfusk/monad.rb', line 59

def bind_discard(m, k)
  bind_pass(m) { |_| k }
end

#bind_pass(m, &b) ⇒ Object

sequentially compose two actions, passing any value produced by the first as an argument to the second

implement me!

Raises:

  • (NotImplementedError)


51
52
53
# File 'lib/obfusk/monad.rb', line 51

def bind_pass(m, &b)
  raise NotImplementedError
end

#fmap(m, f = nil, &b) ⇒ Object

map monad (i.e. functor)



64
65
66
# File 'lib/obfusk/monad.rb', line 64

def fmap(m, f = nil, &b)
  g = f || b; bind(m) { |k| mreturn g[k] }
end

#join(m) ⇒ Object

flatten monad



69
70
71
# File 'lib/obfusk/monad.rb', line 69

def join(m)
  bind(m) { |k| k }
end

#mreturn(x) ⇒ Object

inject a value into the monadic type

implement me!

Raises:

  • (NotImplementedError)


24
25
26
# File 'lib/obfusk/monad.rb', line 24

def mreturn(x)
  raise NotImplementedError
end

#pipeline(m, *fs) ⇒ Object

concatenate a sequence of binds



74
75
76
77
# File 'lib/obfusk/monad.rb', line 74

def pipeline(m, *fs)
  a = -> f, x { f.is_a?(::Proc) ? f[x] : f }
  fs.empty? ? m : m.bind { |x| pipeline a[fs.first,x], *fs.drop(1) }
end

#return(x) ⇒ Object

alias for mreturn



29
30
31
# File 'lib/obfusk/monad.rb', line 29

def return(x)
  mreturn x
end

#sequence(*ms) ⇒ Object

evaluate each action in the sequence from left to right, and collect the results



81
82
83
84
85
# File 'lib/obfusk/monad.rb', line 81

def sequence(*ms)
  ms.inject(mreturn []) do |m,k|
    bind(m) { |xs| bind(k) { |x| mreturn xs+[x] } }
  end
end

#sequence_(*ms) ⇒ Object

evaluate each action in the sequence from left to right, and ignore the results



89
90
91
# File 'lib/obfusk/monad.rb', line 89

def sequence_(*ms)
  (ms + [mreturn(nil)]).inject { |m,k| bind(m, k) }
end