consequence 0.2.2 → 0.2.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 35e897cf0811f0e794d208bfcff9c243f86fd167
4
- data.tar.gz: 4d71d729915727771f5ae6e9263bbf1a72fc0093
3
+ metadata.gz: 1d9f0c8c6460d68c6920b23b9d54b164d5e89d6e
4
+ data.tar.gz: 9b94446f09dbf982fb67043adc34dff1646b5043
5
5
  SHA512:
6
- metadata.gz: 434bcae89a6fad08652e5d697a6f9a3ea3e2eadcf6393a68827b087680c1cfa7d49e14546373b45a3380dd1268d5383e647bfa196ddbd38bc1917c1130ef50bf
7
- data.tar.gz: efd3cb4d3e8bd01b2d2fb99aae2a1ce69257baa7d7da55edb37428e58560b69d1860f2438bfe8cb7229321c62bbc2161da3714d1f2675f003872c743ef1c6980
6
+ metadata.gz: 52332a52917ef7cc1359d80e9a667cdaff60593a393d035d0f2091f03eb4ec01ec914ac68923bee4f687412349122aff6c7b6af02bc6fad5dde886fc29889dc6
7
+ data.tar.gz: 879ea1c9cdebb84d14e8f95e303f7f76bfcd6188fc820a6355092e5a396cddaa7da6dbd1761191d76b78f9f70293cb3b5e3b1329de346ac45ceac199ff8fae8e
data/README.md CHANGED
@@ -1,5 +1,6 @@
1
1
  # Consequence
2
2
 
3
+ [![Build Status](https://travis-ci.org/mushishi78/consequence.svg?branch=master)](https://travis-ci.org/mushishi78/consequence)
3
4
  [![Gem Version](https://badge.fury.io/rb/consequence.svg)](http://badge.fury.io/rb/consequence)
4
5
 
5
6
  Simple monad implementation with clear and consistent syntax.
@@ -41,7 +42,7 @@ Foo[0] == Foo[0] # true
41
42
 
42
43
  Monads have two main operations `>>` and `<<`.
43
44
 
44
- Both take a proc for their only argument. The supplied proc can take 0-2 arguments and the monad will match them, even if it's a lamda or method object with arity checking.
45
+ Both take an object with a `#call` method, such as a proc, for their only argument. The `#call` method can take 0-2 arguments and the monad will match them, even if it's a lamda or method object with arity checking.
45
46
 
46
47
  It's first argument will be passed the monads value:
47
48
 
@@ -61,13 +62,13 @@ Foo[0] << ->(v, m) { puts v if m.is_a?(Foo) }
61
62
 
62
63
  The `>>` operation may be variously thought of as the 'map', 'bind' or 'join' operations, but has been left unnamed to avoid any specific connotations.
63
64
 
64
- It takes the result of the proc given to it and passes it on:
65
+ It takes the result of the argument's `#call` method and passes it on:
65
66
 
66
67
  ``` ruby
67
68
  Foo[0] >> ->(v) { Bar[v] } # Bar[0]
68
69
  ```
69
70
 
70
- If it return's a result that is not a monad, it is wrapped up in one so the chain can continue:
71
+ If the returned result that is not a monad, it is wrapped up in one so the chain can continue:
71
72
 
72
73
  ``` ruby
73
74
  Foo[0] >> ->(v) { v + 1 } # Foo[1]
@@ -77,7 +78,7 @@ Foo[0] >> ->(v) { v + 1 } # Foo[1]
77
78
 
78
79
  The `<<` operation may be thought of as the 'pipe' operation.
79
80
 
80
- It calls the proc given to it, but ignores it's return value:
81
+ It calls the argument's `#call` method, but ignores the return value:
81
82
 
82
83
  ``` ruby
83
84
  Foo[0] << ->(v) { v + 1 } # Foo[0]
@@ -91,28 +92,6 @@ puts @side_effect
91
92
  # $ 1
92
93
  ```
93
94
 
94
- ### `#to_proc`
95
-
96
- Before either operation calls a proc, the `#to_proc` method is called on it. This can be useful if the operation is given an object that is no a proc, but has a `#to_proc` method that returns one.
97
-
98
- A good example of this is the Symbol object, whose `#to_proc` method supplies a proc that sends the symbol as a message to its first argument. In this case this means calling that method on the value:
99
-
100
- ``` ruby
101
- Foo[[1, 4, 7]] >> :pop # Foo[7]
102
- ```
103
-
104
- This also can be used to make a composition syntax, by writing a `#to_proc` method for a monad:
105
-
106
- ``` ruby
107
- class Add < Monad
108
- def to_proc
109
- ->(v) { v + value }
110
- end
111
- end
112
-
113
- Add[1] >> Add[4] >> Add[6] # Add[11]
114
- ```
115
-
116
95
  ## Built-In Types
117
96
 
118
97
  ### NullMonad
@@ -123,7 +102,7 @@ The `NullMonad` is a monad whose `>>` and `<<` operations have been overriden to
123
102
  NullMonad[0] >> ->(v) { v + 1 } # Consequence::NullMonad[0]
124
103
  ```
125
104
 
126
- This is different from the `<<` operation, because the proc isn't even run, so can cause no side effects:
105
+ This is different from the `<<` operation, because the argument's `#call` method isn't even run, so can cause no side effects:
127
106
 
128
107
  ``` ruby
129
108
  NullMonad[0] << ->(v) { @side_effect = v + 1 }
@@ -155,7 +134,7 @@ Success[0] >> ->(v) { 5 / v }
155
134
  # Consequence::Failure[#<ZeroDivisionError: divided by 0>]
156
135
  ```
157
136
 
158
- A `Failure` monad is a subclass of the `NullMonad` so all successive chained procs are ignored.
137
+ A `Failure` monad is a subclass of the `NullMonad` so all successive chained operations are ignored.
159
138
 
160
139
  Both `Success` and `Failure` respond to the `#succeeded?` and `#failed?` query methods in the way you'd expect:
161
140
 
@@ -176,7 +155,7 @@ A `Something` monad wraps up a nil result in a `Nothing` monad:
176
155
  Something[[1, 3, 5]] >> ->(v) { v[4] } # Consequence::Nothing[nil]
177
156
  ```
178
157
 
179
- A `Nothing` monad is also a subclass of the `NullMonad` so all successive chained procs are ignored. This prevents `MissingMethod` errors from trying to call a method on a `nil`.
158
+ A `Nothing` monad is also a subclass of the `NullMonad` so all successive chained operations are ignored. This prevents `MissingMethod` errors from trying to call a method on a `nil`.
180
159
 
181
160
  A `Nothing` responds positively to the `#nil?` method:
182
161
 
@@ -208,6 +187,16 @@ Something[dangrous_hash][:user][:orders][1][:price] # Consequence::Something[3.9
208
187
  Something[dangrous_hash][:user][:orders][2][:price] # Consequence::Nothing[nil]
209
188
  ```
210
189
 
190
+ ## `#to_proc`
191
+
192
+ Before either operation calls the argument's `#call` method, the `#to_proc` method is called on it if it has one. This can be useful if the operation is given an object that has no `#call` method, but has a `#to_proc`.
193
+
194
+ A good example of this is the Symbol object, whose `#to_proc` method supplies a proc that sends the symbol as a message to its first argument. In this case this means calling that method on the value:
195
+
196
+ ``` ruby
197
+ Foo[[1, 4, 7]] >> :pop # Foo[7]
198
+ ```
199
+
211
200
  ## Wiki
212
201
 
213
202
  To find some examples and information about utils, [check out the wiki](https://github.com/mushishi78/consequence/wiki) and feel free to contribute to it.
@@ -215,7 +204,6 @@ To find some examples and information about utils, [check out the wiki](https://
215
204
  ## Inspirations
216
205
 
217
206
  * [Deterministic](https://github.com/pzol/deterministic)
218
- * [Kleisli](https://github.com/txus/kleisli)
219
207
  * [Refactoring Ruby with Monads](https://www.youtube.com/watch?v=J1jYlPtkrqQ&feature=youtu.be&a)
220
208
 
221
209
  ## Installation
@@ -1,17 +1,17 @@
1
1
  require 'consequence/monad'
2
2
 
3
3
  module Consequence
4
- class Eventually < Monad
5
- def execute(proc)
6
- value.(proc)
7
- end
4
+ class Eventually < Monad
5
+ def execute(proc)
6
+ value.(proc)
7
+ end
8
8
 
9
- def <<(_); self end
9
+ def <<(_); self end
10
10
 
11
- private
11
+ private
12
12
 
13
- def bind(proc)
14
- ->(callback) { execute(proc.(callback)) }
15
- end
16
- end
13
+ def bind(proc)
14
+ ->(callback) { execute(proc.(callback)) }
15
+ end
16
+ end
17
17
  end
@@ -10,12 +10,13 @@ module Consequence
10
10
 
11
11
  attr_reader :value
12
12
 
13
- def >>(proc)
14
- wrap(bind(proc.to_proc))
13
+ def >>(obj)
14
+ obj = obj.to_proc if obj.respond_to?(:to_proc)
15
+ wrap(bind(obj))
15
16
  end
16
17
 
17
- def <<(proc)
18
- bind(proc.to_proc)
18
+ def <<(obj)
19
+ bind(obj.to_proc)
19
20
  self
20
21
  end
21
22
 
@@ -33,12 +34,17 @@ module Consequence
33
34
 
34
35
  private
35
36
 
36
- def bind(proc)
37
- proc.call(*args_for(proc))
37
+ def bind(obj)
38
+ obj.call(*args_for(obj))
38
39
  end
39
40
 
40
- def args_for(proc)
41
- [value, self][0, proc.arity.abs]
41
+ def args_for(obj)
42
+ [value, self][0, arity(obj)]
43
+ end
44
+
45
+ def arity(obj)
46
+ method = obj.respond_to?(:arity) ? obj : obj.method(:call)
47
+ method.arity.abs
42
48
  end
43
49
 
44
50
  def wrap(value)
@@ -3,16 +3,16 @@ require 'consequence/delegates_to_value'
3
3
 
4
4
  module Consequence
5
5
  class Something < Monad
6
- include DelegatesToValue
6
+ include DelegatesToValue
7
7
 
8
- def >>(proc)
8
+ def >>(obj)
9
9
  result = super
10
10
  result.value.nil? ? Nothing[nil] : result
11
11
  end
12
12
  end
13
13
 
14
14
  class Nothing < NullMonad
15
- include DelegatesToValue
15
+ include DelegatesToValue
16
16
 
17
17
  def nil?; true end
18
18
  end
@@ -2,13 +2,13 @@ require 'consequence/monad'
2
2
 
3
3
  module Consequence
4
4
  class Success < Monad
5
- def >>(proc)
5
+ def >>(obj)
6
6
  super
7
7
  rescue => err
8
8
  Failure[err]
9
9
  end
10
10
 
11
- def <<(proc)
11
+ def <<(obj)
12
12
  super
13
13
  rescue => err
14
14
  Failure[err]
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: consequence
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Max White
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-01-16 00:00:00.000000000 Z
11
+ date: 2015-01-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec