ruby-monads 0.1.0 → 0.2.0
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 +35 -14
- data/lib/monads/result.rb +7 -1
- data/ruby-monads.gemspec +1 -1
- data/test/result_test.rb +63 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1af43d29c4276218767541b961ca19fb65e5f48c35cfd880f33fd47a23a5c7e4
|
4
|
+
data.tar.gz: 3da1575ae115a6c572720550a4b08b651ceaa04b75d43a9d643f8658e3b28f9a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 53328e008e31ecb7d4f08323e1c6665d7e93fbf72224cf5ee29b573e88bba14b4c67b9e740948ecd458281b48269589a8cd903144eb3ec2110981b1430e8e13d
|
7
|
+
data.tar.gz: e33053dfad28ca2ba867061f35121e139c7aef399971fa8c92128840d16951c636526dbf8979cae712dc37e9a0befd70cd061f2b6d357bddd3181933bf892a6a
|
data/README.md
CHANGED
@@ -30,20 +30,41 @@ The maybe monad returns one of the following classes, wether it wraps a value or
|
|
30
30
|
#### Examples
|
31
31
|
|
32
32
|
```ruby
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
Maybe.unit(
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
Maybe.unit(
|
33
|
+
Maybe.unit("Hello, World!") # => #<Monads::Just @value="Hello, World!">
|
34
|
+
Maybe.unit(nil) # => #<Monads::Nothing>
|
35
|
+
|
36
|
+
Maybe.unit("Hello, World!").upcase # => #<Monads::Just @value="HELLO, WORLD!">
|
37
|
+
Maybe.unit("Hello, World!").upcase.split.unwrap([]) # => ["HELLO,", "WORLD!"]
|
38
|
+
Maybe.unit("Hello, World!").bind { |v| Maybe.unit(nil) } # => #<Monads::Nothing>
|
39
|
+
Maybe.unit("Hello, World!").fmap { |v| v.gsub(/\w/, "*") } # => #<Monads::Just @value="*****, *****!">
|
40
|
+
Maybe.unit(Maybe.unit("Hello, World!")).join # => #<Monads::Just @value="Hello, World!">
|
41
|
+
|
42
|
+
Maybe.unit(nil).upcase # => #<Monads::Nothing>
|
43
|
+
Maybe.unit(nil).upcase.split.unwrap([]) # => []
|
44
|
+
Maybe.unit(nil).bind { |v| Maybe.unit("Hello, World!") } # => #<Monads::Maybe.unit(nil)>
|
45
|
+
Maybe.unit(nil).fmap { |v| v.gsub(/\w/, "*") } # => #<Monads::Nothing>
|
46
|
+
Maybe.unit(Maybe.unit(nil)).join # => #<Monads::Nothing>
|
47
|
+
```
|
48
|
+
|
49
|
+
### Result
|
50
|
+
|
51
|
+
The result monad returns one of the following classes, wether it wraps an error or not:
|
52
|
+
|
53
|
+
- `Result.unit(42)` returns an instance of `Success` wrapping the `42` value
|
54
|
+
- `Result.unit(StandardError.new)` returns an instance of `Failure` wrapping the given error
|
55
|
+
|
56
|
+
#### Examples
|
57
|
+
|
58
|
+
```ruby
|
59
|
+
Result.unit("Hello, World!") # => #<Monads::Success @value="Hello, World!">
|
60
|
+
Result.unit(StandardError.new("Wrong!")) # => #<Monads::Failure @value=#<StandardError: Wrong!>>
|
61
|
+
|
62
|
+
Result
|
63
|
+
.unit("Hello, World!") # => #<Monads::Success @value="Hello, World!">
|
64
|
+
.upcase # => #<Monads::Success @value="HELLO, WORLD!">
|
65
|
+
.even # => #<Monads::Failure @value=#<NoMethodError: undefined method `even?' for "HELLO, WORLD!":String>>
|
66
|
+
.split # => #<Monads::Failure @value=#<NoMethodError: undefined method `even?' for "HELLO, WORLD!":String>>
|
67
|
+
.unwrap("default") # "default"
|
47
68
|
```
|
48
69
|
|
49
70
|
## Why this gem
|
data/lib/monads/result.rb
CHANGED
@@ -6,7 +6,13 @@ module Monads
|
|
6
6
|
|
7
7
|
# unit :: a -> M a
|
8
8
|
def self.unit(value)
|
9
|
-
value.is_a?(FAILURE_TRIGGER)
|
9
|
+
if value.is_a?(FAILURE_TRIGGER) || value.is_a?(Failure)
|
10
|
+
Failure.new(value)
|
11
|
+
else
|
12
|
+
Success.new(value)
|
13
|
+
end
|
14
|
+
rescue => error
|
15
|
+
Failure.new(error)
|
10
16
|
end
|
11
17
|
|
12
18
|
# bind :: (a -> M b) -> M a -> M b
|
data/ruby-monads.gemspec
CHANGED
data/test/result_test.rb
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
print "\n\"Result\" monad test suite"
|
2
|
+
|
3
|
+
setup do
|
4
|
+
[Success.new(42), Failure.new(StandardError.new("Wrong!"))]
|
5
|
+
end
|
6
|
+
|
7
|
+
test "Result::new" do
|
8
|
+
assert_raise NoMethodError do Result.new(42) end
|
9
|
+
|
10
|
+
assert_raise TypeError do Success.new(StandardError.new) end
|
11
|
+
assert Success.new(42).is_a?(Success)
|
12
|
+
|
13
|
+
assert_raise TypeError do Failure.new(42) end
|
14
|
+
assert Failure.new(StandardError.new).is_a?(Failure)
|
15
|
+
end
|
16
|
+
|
17
|
+
test "Result::unit" do |success, failure|
|
18
|
+
assert success.is_a?(Result)
|
19
|
+
assert success.is_a?(Success)
|
20
|
+
assert !success.is_a?(Failure)
|
21
|
+
|
22
|
+
assert failure.is_a?(Result)
|
23
|
+
assert !failure.is_a?(Success)
|
24
|
+
assert failure.is_a?(Failure)
|
25
|
+
|
26
|
+
assert Result.unit(success).is_a?(Success)
|
27
|
+
assert Result.unit(failure).is_a?(Failure)
|
28
|
+
end
|
29
|
+
|
30
|
+
test "Result#bind" do |success, failure|
|
31
|
+
assert success.bind { |v| Result.unit(v / 2) }.is_a?(Success)
|
32
|
+
assert success.bind { |v| Result.unit(v / 0) }.is_a?(Failure)
|
33
|
+
assert success.bind { |v| v / 0 }.is_a?(Failure)
|
34
|
+
|
35
|
+
assert failure.bind { |v| Result.unit(42) }.is_a?(Failure)
|
36
|
+
assert failure.bind { |v| Result.unit(StandardError.new) }.is_a?(Failure)
|
37
|
+
assert failure.bind { |v| v / 2 }.is_a?(Failure)
|
38
|
+
end
|
39
|
+
|
40
|
+
test "Result#fmap" do |success, failure|
|
41
|
+
assert success.fmap(&:even?).is_a?(Success)
|
42
|
+
assert success.fmap { |v| v / 0 }.is_a?(Failure)
|
43
|
+
|
44
|
+
assert failure.fmap(&:even?).is_a?(Failure)
|
45
|
+
assert failure.fmap { |v| v / 0 }.is_a?(Failure)
|
46
|
+
end
|
47
|
+
|
48
|
+
test "Result#join" do |success, failure|
|
49
|
+
assert_equal Result.unit(success).join.unwrap("default"), 42
|
50
|
+
assert_equal Result.unit(failure).join.unwrap("default"), "default"
|
51
|
+
end
|
52
|
+
|
53
|
+
test "Result#unwrap" do |success, failure|
|
54
|
+
assert_equal success.unwrap("default"), 42
|
55
|
+
assert_equal success.unwrap(nil), 42
|
56
|
+
assert_equal failure.unwrap("default"), "default"
|
57
|
+
assert_equal failure.unwrap(nil), nil
|
58
|
+
end
|
59
|
+
|
60
|
+
test "Result accepts methods chaining" do |success, failure|
|
61
|
+
assert_equal success.next.div(13).to_f.unwrap(1.0), 3.0
|
62
|
+
assert_equal failure.next.div(13).to_f.unwrap(1.0), 1.0
|
63
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-monads
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Guillaume BOUDON
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-08-
|
11
|
+
date: 2020-08-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: cutest
|
@@ -48,6 +48,7 @@ files:
|
|
48
48
|
- ruby-monads.gemspec
|
49
49
|
- test/helper.rb
|
50
50
|
- test/maybe_test.rb
|
51
|
+
- test/result_test.rb
|
51
52
|
homepage: https://github.com/guillaumeboudon/ruby-monads
|
52
53
|
licenses:
|
53
54
|
- MIT
|