consequence 0.2.2 → 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
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