arrows 0.0.11 → 0.0.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +55 -0
- data/lib/arrows.rb +13 -2
- data/lib/arrows/either.rb +3 -0
- data/lib/arrows/proc.rb +5 -0
- data/lib/arrows/version.rb +1 -1
- data/pics/compose.mermaid +3 -0
- data/pics/compose.mermaid.png +0 -0
- data/pics/concurrent.mermaid +5 -0
- data/pics/concurrent.mermaid.png +0 -0
- data/pics/fanout.mermaid +7 -0
- data/pics/fanout.mermaid.png +0 -0
- data/pics/feedback.mermaid +7 -0
- data/pics/feedback.mermaid.png +0 -0
- data/pics/fmap.mermaid +4 -0
- data/pics/fmap.mermaid.png +0 -0
- data/pics/fork.mermaid +4 -0
- data/pics/fork.mermaid.png +0 -0
- data/spec/arrows/proc_spec.rb +21 -0
- metadata +14 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 87e62ace5a7ed0350a0f2933213138fbc4adf91d
|
4
|
+
data.tar.gz: b3d590924508a3a8ee58b1b83c4f45d9df39244c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e8a05896a7bc8593eaa83585fb71ab2957daf737597873639ffbe8653f2a4596dc9bf2220ec587200bc6066a52d342f52c13fae33b33a2397e4fef0d4735681b
|
7
|
+
data.tar.gz: cbc2435c3618794b04fad75e7ebe38f2a1a5d2fbcdd4323768774e5c3cf359a3190a899cbf1eb34fe92999e01208f67108441227d1c8be0d52d014d38ef4722c
|
data/README.md
CHANGED
@@ -18,6 +18,12 @@ x -> H -> z
|
|
18
18
|
|
19
19
|
As in we pipe what F poops out into the mouth of G a la Human Centipede
|
20
20
|
|
21
|
+
```ruby
|
22
|
+
f = Arrows.lift -> (apple) { apple.to_orange }
|
23
|
+
g = Arrows.lift -> (orange) { orange.to_kiwi }
|
24
|
+
apple_to_kiwi = f >> g
|
25
|
+
```
|
26
|
+

|
21
27
|
|
22
28
|
### Applicative composition
|
23
29
|
Calls map (in Haskell, they generalize it to fmap) on the data passed in
|
@@ -28,15 +34,64 @@ x -> F -> y and [x]
|
|
28
34
|
Returns
|
29
35
|
[x] -> F -> [z]
|
30
36
|
|
37
|
+
```ruby
|
38
|
+
apples = Arrows.lift [apple, apple, apple]
|
39
|
+
apple_to_kiwi = Arrows.lift -> (apple) { apple.to_kiwi }
|
40
|
+
kiwis = apples >= apple_to_kiwi
|
41
|
+
```
|
42
|
+

|
43
|
+
|
31
44
|
### Arrow fan out
|
32
45
|
x -> y
|
33
46
|
x -> z
|
34
47
|
becomes
|
35
48
|
x -> [y,z]
|
36
49
|
|
50
|
+
```ruby
|
51
|
+
apple_to_orange = Arrows.lift -> (apple) { apple.to_orange }
|
52
|
+
apple_to_kiwi = Arrows.lift -> (apple) { apple.to_kiwi }
|
53
|
+
orange_and_kiwi = Arrows.lift(apple) >> (apple_to_orange / apple_to_kiwi)
|
54
|
+
```
|
55
|
+

|
56
|
+
|
37
57
|
### Arrow Fork
|
38
58
|
f ^ g produces a proc that takes in a Either, and if either is good, f is evaluated, if either is evil, g is evaluated
|
39
59
|
|
60
|
+
```ruby
|
61
|
+
apple_to_orange = Arrows.lift -> (apple) { apple.to_orange }
|
62
|
+
apple_to_kiwi = Arrows.lift -> (apple) { apple.to_kiwi }
|
63
|
+
orange = Arrows.lift(apple) >> Arrows::Good >> (apple_to_orange ^ apple_to_kiwi)
|
64
|
+
kiwi = Arrows.lift(apple) >> Arrows::Evil >> (apple_to_orange ^ apple_to_kiwi)
|
65
|
+
```
|
66
|
+

|
67
|
+
|
68
|
+
### ArrowLoop
|
69
|
+
step <=> chose produces a proc that cycles between step and chose until chose returns a good either. Then returns whatever was in the good either
|
70
|
+
|
71
|
+
```ruby
|
72
|
+
context '<=> feedback' do
|
73
|
+
let(:step) { Arrows.lift -> (arg_acc) { [arg_acc.first - 1, arg_acc.reduce(&:*)] } }
|
74
|
+
let(:chose) { Arrows.lift -> (arg_acc) { arg_acc.first < 1 ? Arrows.good(arg_acc.last) : Arrows.evil(arg_acc) } }
|
75
|
+
let(:factorial) { step <=> chose }
|
76
|
+
context '120' do
|
77
|
+
let(:one_twenty) { Arrows.lift(5) >> factorial }
|
78
|
+
subject { one_twenty.call }
|
79
|
+
specify { should eq 120 }
|
80
|
+
end
|
81
|
+
context '1' do
|
82
|
+
let(:one) { Arrows.lift(1) >> factorial }
|
83
|
+
subject { one.call }
|
84
|
+
specify { should eq 1 }
|
85
|
+
end
|
86
|
+
context '0' do
|
87
|
+
let(:zero) { Arrows.lift(0) >> factorial }
|
88
|
+
subject { zero.call }
|
89
|
+
specify { should eq 0 }
|
90
|
+
end
|
91
|
+
end
|
92
|
+
```
|
93
|
+

|
94
|
+
|
40
95
|
## Memoization
|
41
96
|
```ruby
|
42
97
|
@some_process = Arrows.lift -> (a) { a }
|
data/lib/arrows.rb
CHANGED
@@ -4,6 +4,17 @@ module Arrows
|
|
4
4
|
require 'arrows/either'
|
5
5
|
require 'arrows/proc'
|
6
6
|
class << self
|
7
|
+
def feedback(merge, split)
|
8
|
+
Arrows::Proc.new do |args|
|
9
|
+
single = merge.call [args]
|
10
|
+
either = split.call single
|
11
|
+
while not either.good?
|
12
|
+
single = merge.call either.payload
|
13
|
+
either = split.call single
|
14
|
+
end
|
15
|
+
either.payload
|
16
|
+
end
|
17
|
+
end
|
7
18
|
def fork(f,g)
|
8
19
|
Arrows::Proc.new do |either|
|
9
20
|
either.good? ? f[either.payload] : g[either.payload]
|
@@ -23,11 +34,11 @@ module Arrows
|
|
23
34
|
def fmap(xs, f)
|
24
35
|
Arrows::Proc.new { |args| xs[args].map { |x| f[x] } }
|
25
36
|
end
|
26
|
-
def good(x)
|
37
|
+
def good(x=nil)
|
27
38
|
return x if x.respond_to?(:good?) && x.respond_to?(:payload)
|
28
39
|
Arrows::Either.new true, x
|
29
40
|
end
|
30
|
-
def evil(x)
|
41
|
+
def evil(x=nil)
|
31
42
|
return x if x.respond_to?(:good?) && x.respond_to?(:payload)
|
32
43
|
Arrows::Either.new false, x
|
33
44
|
end
|
data/lib/arrows/either.rb
CHANGED
data/lib/arrows/proc.rb
CHANGED
data/lib/arrows/version.rb
CHANGED
Binary file
|
Binary file
|
data/pics/fanout.mermaid
ADDED
Binary file
|
Binary file
|
data/pics/fmap.mermaid
ADDED
Binary file
|
data/pics/fork.mermaid
ADDED
Binary file
|
data/spec/arrows/proc_spec.rb
CHANGED
@@ -29,6 +29,27 @@ RSpec.describe Arrows::Proc do
|
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
|
+
context '<=> feedback' do
|
33
|
+
let(:step) { Arrows.lift -> (arg_acc) { [arg_acc.first - 1, arg_acc.reduce(&:*)] } }
|
34
|
+
let(:chose) { Arrows.lift -> (arg_acc) { arg_acc.first < 1 ? Arrows.good(arg_acc.last) : Arrows.evil(arg_acc) } }
|
35
|
+
let(:factorial) { step <=> chose }
|
36
|
+
context '120' do
|
37
|
+
let(:one_twenty) { Arrows.lift(5) >> factorial }
|
38
|
+
subject { one_twenty.call }
|
39
|
+
specify { should eq 120 }
|
40
|
+
end
|
41
|
+
context '1' do
|
42
|
+
let(:one) { Arrows.lift(1) >> factorial }
|
43
|
+
subject { one.call }
|
44
|
+
specify { should eq 1 }
|
45
|
+
end
|
46
|
+
context '0' do
|
47
|
+
let(:zero) { Arrows.lift(0) >> factorial }
|
48
|
+
subject { zero.call }
|
49
|
+
specify { should eq 0 }
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
32
53
|
context '>> composition' do
|
33
54
|
let(:times2) { -> (x) { x * 2 } }
|
34
55
|
let(:plus3) { -> (x) { x + 3 } }
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: arrows
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.12
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Thomas Chen
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-12-
|
11
|
+
date: 2014-12-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -72,6 +72,18 @@ files:
|
|
72
72
|
- lib/arrows/either.rb
|
73
73
|
- lib/arrows/proc.rb
|
74
74
|
- lib/arrows/version.rb
|
75
|
+
- pics/compose.mermaid
|
76
|
+
- pics/compose.mermaid.png
|
77
|
+
- pics/concurrent.mermaid
|
78
|
+
- pics/concurrent.mermaid.png
|
79
|
+
- pics/fanout.mermaid
|
80
|
+
- pics/fanout.mermaid.png
|
81
|
+
- pics/feedback.mermaid
|
82
|
+
- pics/feedback.mermaid.png
|
83
|
+
- pics/fmap.mermaid
|
84
|
+
- pics/fmap.mermaid.png
|
85
|
+
- pics/fork.mermaid
|
86
|
+
- pics/fork.mermaid.png
|
75
87
|
- spec/arrows/proc_spec.rb
|
76
88
|
- spec/spec_helper.rb
|
77
89
|
homepage: http://github.com/foxnewsnetwork/arrows
|