module Obfusk::Monad::ClassMethods

Public Instance Methods

bind(m, k = nil, &b) click to toggle source

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 “`

# 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) click to toggle source

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

implement me!

# File lib/obfusk/monad.rb, line 59
def bind_discard(m, k)
  bind_pass(m) { |_| k }
end
bind_pass(m, &b) click to toggle source

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

implement me!

# File lib/obfusk/monad.rb, line 51
def bind_pass(m, &b)
  raise NotImplementedError
end
fmap(m, f = nil, &b) click to toggle source

map monad (i.e. functor)

# 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) click to toggle source

flatten monad

# File lib/obfusk/monad.rb, line 69
def join(m)
  bind(m) { |k| k }
end
mreturn(x) click to toggle source

inject a value into the monadic type

implement me!

# File lib/obfusk/monad.rb, line 24
def mreturn(x)
  raise NotImplementedError
end
pipeline(m, *fs) click to toggle source

concatenate a sequence of binds

# 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) click to toggle source

alias for mreturn

# File lib/obfusk/monad.rb, line 29
def return(x)
  mreturn x
end
sequence(*ms) click to toggle source

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

# 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) click to toggle source

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

# File lib/obfusk/monad.rb, line 89
def sequence_(*ms)
  (ms + [mreturn(nil)]).inject { |m,k| bind(m, k) }
end