Module: Arrows

Defined in:
lib/arrows.rb,
lib/arrows/version.rb

Defined Under Namespace

Classes: Either, Proc

Constant Summary collapse

ID =
lift { |x| x }
Good =
lift { |x| good x }
Evil =
lift { |x| evil x }
Die =
lift { |x| throw x }
VERSION =
"0.1.0"

Class Method Summary collapse

Class Method Details

.arrow_like?(x) ⇒ Boolean

Returns:

  • (Boolean)


56
57
58
59
60
61
62
63
64
# File 'lib/arrows.rb', line 56

def arrow_like?(x)
   proc_like?(x) && 
   x.arity == 1 && 
   x.respond_to?(:>=) && 
   x.respond_to?(:>>) && 
   x.respond_to?(:^) && 
   x.respond_to?(:/) && 
   x.respond_to?(:%)
end

.compose(f, g) ⇒ Object



31
32
33
# File 'lib/arrows.rb', line 31

def compose(f,g)
  Arrows::Proc.new { |args| g[f[args]] }
end

.concurrent(f, g) ⇒ Object



23
24
25
26
27
# File 'lib/arrows.rb', line 23

def concurrent(f,g)
  Arrows::Proc.new do |args| 
    [f[args.first], g[args.last]]
  end
end

.evil(x = nil) ⇒ Object



41
42
43
44
# File 'lib/arrows.rb', line 41

def evil(x=nil)
  return x if x.respond_to?(:good?) && x.respond_to?(:payload)
  Arrows::Either.new false, x
end

.fanout(f, g) ⇒ Object



28
29
30
# File 'lib/arrows.rb', line 28

def fanout(f,g)
  Arrows::Proc.new { |args| [f[args], g[args]] }
end

.feedback(merge, split) ⇒ Object



7
8
9
10
11
12
13
14
15
16
17
# File 'lib/arrows.rb', line 7

def feedback(merge, split)
  Arrows::Proc.new do |args|
    single = merge.call [args]
    either = split.call single
    while not either.good?
      single = merge.call either.payload
      either = split.call single
    end
    either.payload
  end
end

.fmap(xs, f) ⇒ Object



34
35
36
# File 'lib/arrows.rb', line 34

def fmap(xs, f)
  Arrows::Proc.new { |args| xs[args].map { |x| f[x] }  }
end

.fork(f, g) ⇒ Object



18
19
20
21
22
# File 'lib/arrows.rb', line 18

def fork(f,g)
  Arrows::Proc.new do |either|
    either.good? ? f[either.payload] : g[either.payload]
  end
end

.good(x = nil) ⇒ Object



37
38
39
40
# File 'lib/arrows.rb', line 37

def good(x=nil)
  return x if x.respond_to?(:good?) && x.respond_to?(:payload)
  Arrows::Either.new true, x
end

.lift(x = nil) ⇒ Object



45
46
47
48
49
50
# File 'lib/arrows.rb', line 45

def lift(x=nil)
  return Arrows::Proc.new { |args| yield args } if block_given?
  return x if arrow_like? x
  return wrap_proc x if proc_like? x
  Arrows::Proc.new { |args| x }
end

.polarize(x = nil) ⇒ Object



51
52
53
54
55
# File 'lib/arrows.rb', line 51

def polarize(x=nil)
  return lift { |args| yield(args) ? good(args) : evil(args) } if block_given?
  return lift { |args| x.call(args) ? good(args) : evil(args) } if proc_like? x
  lift { |args| x ? good(args) : evil(args) }
end

.proc_like?(x) ⇒ Boolean

Returns:

  • (Boolean)


65
66
67
# File 'lib/arrows.rb', line 65

def proc_like?(x)
  x.respond_to?(:call) && x.respond_to?(:arity)
end

.wrap_proc(f) ⇒ Object



68
69
70
71
72
# File 'lib/arrows.rb', line 68

def wrap_proc(f)
  Arrows::Proc.new do |args|
    f[args]
  end
end