fear 0.11.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (110) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +0 -1
  3. data/.rubocop.yml +18 -0
  4. data/.travis.yml +0 -3
  5. data/CHANGELOG.md +12 -1
  6. data/Gemfile +1 -0
  7. data/{gemfiles/dry_equalizer_0.2.1.gemfile.lock → Gemfile.lock} +21 -12
  8. data/README.md +594 -241
  9. data/Rakefile +166 -219
  10. data/benchmarks/README.md +1 -0
  11. data/benchmarks/dry_do_vs_fear_for.txt +11 -0
  12. data/benchmarks/dry_some_fmap_vs_fear_some_map.txt +11 -0
  13. data/benchmarks/factorial.txt +16 -0
  14. data/benchmarks/fear_gaurd_and1_vs_new.txt +13 -0
  15. data/benchmarks/fear_gaurd_and2_vs_and.txt +13 -0
  16. data/benchmarks/fear_gaurd_and3_vs_and_and.txt +13 -0
  17. data/benchmarks/fear_pattern_extracting_with_vs_without_cache.txt +11 -0
  18. data/benchmarks/fear_pattern_matching_construction_vs_execution.txt +13 -0
  19. data/benchmarks/pattern_matching_dry_vs_qo_vs_fear_try.txt +14 -0
  20. data/benchmarks/pattern_matching_qo_vs_fear_pattern_extraction.txt +11 -0
  21. data/benchmarks/pattern_matching_qo_vs_fear_try_execution.txt +11 -0
  22. data/examples/pattern_extracting.rb +15 -0
  23. data/examples/pattern_matching_binary_tree_set.rb +96 -0
  24. data/examples/pattern_matching_number_in_words.rb +54 -0
  25. data/fear.gemspec +4 -2
  26. data/lib/fear.rb +21 -4
  27. data/lib/fear/either.rb +77 -59
  28. data/lib/fear/either_api.rb +21 -0
  29. data/lib/fear/empty_partial_function.rb +1 -1
  30. data/lib/fear/extractor.rb +108 -0
  31. data/lib/fear/extractor/anonymous_array_splat_matcher.rb +8 -0
  32. data/lib/fear/extractor/any_matcher.rb +15 -0
  33. data/lib/fear/extractor/array_head_matcher.rb +34 -0
  34. data/lib/fear/extractor/array_matcher.rb +38 -0
  35. data/lib/fear/extractor/array_splat_matcher.rb +14 -0
  36. data/lib/fear/extractor/empty_list_matcher.rb +18 -0
  37. data/lib/fear/extractor/extractor_matcher.rb +42 -0
  38. data/lib/fear/extractor/grammar.rb +201 -0
  39. data/lib/fear/extractor/grammar.treetop +129 -0
  40. data/lib/fear/extractor/identifier_matcher.rb +16 -0
  41. data/lib/fear/extractor/matcher.rb +54 -0
  42. data/lib/fear/extractor/matcher/and.rb +36 -0
  43. data/lib/fear/extractor/named_array_splat_matcher.rb +15 -0
  44. data/lib/fear/extractor/pattern.rb +55 -0
  45. data/lib/fear/extractor/typed_identifier_matcher.rb +24 -0
  46. data/lib/fear/extractor/value_matcher.rb +17 -0
  47. data/lib/fear/extractor_api.rb +33 -0
  48. data/lib/fear/failure.rb +32 -10
  49. data/lib/fear/for.rb +14 -69
  50. data/lib/fear/for_api.rb +66 -0
  51. data/lib/fear/future.rb +414 -0
  52. data/lib/fear/future_api.rb +19 -0
  53. data/lib/fear/left.rb +8 -0
  54. data/lib/fear/none.rb +17 -8
  55. data/lib/fear/option.rb +55 -49
  56. data/lib/fear/option_api.rb +38 -0
  57. data/lib/fear/partial_function.rb +9 -12
  58. data/lib/fear/partial_function/empty.rb +1 -1
  59. data/lib/fear/partial_function/guard.rb +8 -20
  60. data/lib/fear/partial_function/lifted.rb +1 -0
  61. data/lib/fear/partial_function_class.rb +10 -0
  62. data/lib/fear/pattern_match.rb +10 -0
  63. data/lib/fear/pattern_matching_api.rb +35 -11
  64. data/lib/fear/promise.rb +87 -0
  65. data/lib/fear/right.rb +8 -0
  66. data/lib/fear/some.rb +22 -3
  67. data/lib/fear/success.rb +22 -1
  68. data/lib/fear/try.rb +82 -67
  69. data/lib/fear/try_api.rb +31 -0
  70. data/lib/fear/unit.rb +28 -0
  71. data/lib/fear/version.rb +1 -1
  72. data/spec/fear/done_spec.rb +3 -3
  73. data/spec/fear/either/mixin_spec.rb +15 -0
  74. data/spec/fear/either_pattern_match_spec.rb +10 -12
  75. data/spec/fear/extractor/array_matcher_spec.rb +228 -0
  76. data/spec/fear/extractor/extractor_matcher_spec.rb +151 -0
  77. data/spec/fear/extractor/grammar_array_spec.rb +23 -0
  78. data/spec/fear/extractor/identified_matcher_spec.rb +47 -0
  79. data/spec/fear/extractor/identifier_matcher_spec.rb +66 -0
  80. data/spec/fear/extractor/pattern_spec.rb +32 -0
  81. data/spec/fear/extractor/typed_identifier_matcher_spec.rb +62 -0
  82. data/spec/fear/extractor/value_matcher_number_spec.rb +77 -0
  83. data/spec/fear/extractor/value_matcher_string_spec.rb +86 -0
  84. data/spec/fear/extractor/value_matcher_symbol_spec.rb +69 -0
  85. data/spec/fear/extractor_api_spec.rb +113 -0
  86. data/spec/fear/extractor_spec.rb +59 -0
  87. data/spec/fear/failure_spec.rb +73 -13
  88. data/spec/fear/for_spec.rb +35 -35
  89. data/spec/fear/future_spec.rb +466 -0
  90. data/spec/fear/guard_spec.rb +4 -4
  91. data/spec/fear/left_spec.rb +40 -14
  92. data/spec/fear/none_spec.rb +28 -12
  93. data/spec/fear/option/mixin_spec.rb +37 -0
  94. data/spec/fear/option_pattern_match_spec.rb +7 -9
  95. data/spec/fear/partial_function_spec.rb +25 -3
  96. data/spec/fear/pattern_match_spec.rb +33 -1
  97. data/spec/fear/promise_spec.rb +94 -0
  98. data/spec/fear/right_spec.rb +37 -9
  99. data/spec/fear/some_spec.rb +32 -6
  100. data/spec/fear/success_spec.rb +32 -4
  101. data/spec/fear/try/mixin_spec.rb +17 -0
  102. data/spec/fear/try_pattern_match_spec.rb +8 -10
  103. data/spec/spec_helper.rb +1 -1
  104. metadata +115 -20
  105. data/Appraisals +0 -32
  106. data/gemfiles/dry_equalizer_0.1.0.gemfile +0 -8
  107. data/gemfiles/dry_equalizer_0.1.0.gemfile.lock +0 -82
  108. data/gemfiles/dry_equalizer_0.2.1.gemfile +0 -8
  109. data/lib/fear/done.rb +0 -22
  110. data/spec/fear/option_spec.rb +0 -15
@@ -0,0 +1 @@
1
+ See Rakefile
@@ -0,0 +1,11 @@
1
+ > bundle exec rake perf:dry:do_vs_fear_for
2
+ Warming up --------------------------------------
3
+ Dry 31.375k i/100ms
4
+ Fear 24.131k i/100ms
5
+ Calculating -------------------------------------
6
+ Dry 360.990k (± 2.7%) i/s - 1.820M in 5.045364s
7
+ Fear 7.212B (±27.2%) i/s - 27.210B in 4.656760s
8
+
9
+ Comparison:
10
+ Fear: 7212177713.5 i/s
11
+ Dry: 360989.8 i/s - 19978.90x slower
@@ -0,0 +1,11 @@
1
+ > bundle exec rake perf:dry:some_fmap_vs_fear_some_map
2
+ Warming up --------------------------------------
3
+ Dry 68.154k i/100ms
4
+ Fear 151.093k i/100ms
5
+ Calculating -------------------------------------
6
+ Dry 884.315k (± 4.1%) i/s - 4.430M in 5.018931s
7
+ Fear 2.481M (± 4.1%) i/s - 12.390M in 5.003728s
8
+
9
+ Comparison:
10
+ Fear: 2480589.0 i/s
11
+ Dry: 884315.1 i/s - 2.81x slower
@@ -0,0 +1,16 @@
1
+ # Depends on `n`, for 100!:
2
+
3
+ > bundle exec rake perf:pattern_matching:factorial
4
+ Warming up --------------------------------------
5
+ Proc 2.395k i/100ms
6
+ Fear 312.000 i/100ms
7
+ Qo 122.000 i/100ms
8
+ Calculating -------------------------------------
9
+ Proc 26.620k (± 2.9%) i/s - 134.120k in 5.042738s
10
+ Fear 3.219k (± 4.1%) i/s - 16.224k in 5.049215s
11
+ Qo 1.250k (± 4.8%) i/s - 6.344k in 5.090745s
12
+
13
+ Comparison:
14
+ Proc: 26620.3 i/s
15
+ Fear: 3219.4 i/s - 8.27x slower
16
+ Qo: 1249.6 i/s - 21.30x slower
@@ -0,0 +1,13 @@
1
+ # It verifies that optimization for Partial Functions with only one guard actually works.
2
+
3
+ > bundle exec rake perf:fear:guard:and1_vs_new
4
+ Warming up --------------------------------------
5
+ Guard.new 173.019k i/100ms
6
+ Guard.and1 268.379k i/100ms
7
+ Calculating -------------------------------------
8
+ Guard.new 171.291B (± 8.4%) i/s - 561.437B
9
+ Guard.and1 266.882B (± 5.9%) i/s - 751.316B
10
+
11
+ Comparison:
12
+ Guard.and1: 266881817299.6 i/s
13
+ Guard.new: 171291386467.1 i/s - 1.56x slower
@@ -0,0 +1,13 @@
1
+ # It verifies that optimization for Partial Functions with two guards actually works.
2
+
3
+ > bundle exec rake perf:fear:guard:and2_vs_guard_and_guard
4
+ Warming up --------------------------------------
5
+ and2 224.836k i/100ms
6
+ Guard#and 211.833k i/100ms
7
+ Calculating -------------------------------------
8
+ and2 224.457B (± 3.8%) i/s - 651.564B
9
+ Guard#and 211.486B (± 3.7%) i/s - 667.936B
10
+
11
+ Comparison:
12
+ and2: 224457051906.8 i/s
13
+ Guard#and: 211485786834.4 i/s - same-ish: difference falls within error
@@ -0,0 +1,13 @@
1
+ # It verifies that optimization for Partial Functions with three guards actually works.
2
+
3
+ > bundle exec rake perf:fear:guard:and3_vs_and_and
4
+ Warming up --------------------------------------
5
+ Guard.and3 236.318k i/100ms
6
+ Guard#and 170.369k i/100ms
7
+ Calculating -------------------------------------
8
+ Guard.and3 235.992B (± 3.4%) i/s - 791.166B
9
+ Guard#and 169.998B (± 4.0%) i/s - 640.637B
10
+
11
+ Comparison:
12
+ Guard.and3: 235992292688.6 i/s
13
+ Guard#and: 169997755111.1 i/s - 1.39x slower
@@ -0,0 +1,11 @@
1
+ > bundle exec rake perf:fear:pattern_extracting_with_vs_without_cache
2
+ Warming up --------------------------------------
3
+ With cache 1.555k i/100ms
4
+ Without cache 164.000 i/100ms
5
+ Calculating -------------------------------------
6
+ With cache 26.159M (±14.7%) i/s - 124.607M in 4.958175s
7
+ Without cache 278.285k (±10.5%) i/s - 1.368M in 4.993567s
8
+
9
+ Comparison:
10
+ With cache: 26159162.8 i/s
11
+ Without cache: 278285.4 i/s - 94.00x slower
@@ -0,0 +1,13 @@
1
+ # So, it's better to avoid building pattern match in runtime
2
+
3
+ > bundle exec rake perf:fear:pattern_matching_construction_vs_execution
4
+ Warming up --------------------------------------
5
+ construction 24.425k i/100ms
6
+ execution 80.516k i/100ms
7
+ Calculating -------------------------------------
8
+ construction 267.887k (± 4.9%) i/s - 1.343M in 5.029005s
9
+ execution 1.085M (± 2.6%) i/s - 5.475M in 5.049775s
10
+
11
+ Comparison:
12
+ execution: 1084968.2 i/s
13
+ construction: 267886.6 i/s - 4.05x slower
@@ -0,0 +1,14 @@
1
+ > bundle exec rake perf:pattern_matching:dry_vs_qo_vs_fear_try
2
+ Warming up --------------------------------------
3
+ Qo 2.958k i/100ms
4
+ Fear 7.127k i/100ms
5
+ Dr::Matcher 13.079k i/100ms
6
+ Calculating -------------------------------------
7
+ Qo 38.872k (± 3.1%) i/s - 195.228k in 5.027249s
8
+ Fear 88.756k (± 3.7%) i/s - 449.001k in 5.066471s
9
+ Dr::Matcher 166.700k (± 3.0%) i/s - 837.056k in 5.026408s
10
+
11
+ Comparison:
12
+ Dr::Matcher: 166699.7 i/s
13
+ Fear: 88755.7 i/s - 1.88x slower
14
+ Qo: 38871.9 i/s - 4.29x slower
@@ -0,0 +1,11 @@
1
+ > bundle exec rake perf:pattern_matching:qo_vs_fear_pattern_extraction
2
+ Warming up --------------------------------------
3
+ Qo 12.352k i/100ms
4
+ Fear 6.841k i/100ms
5
+ Calculating -------------------------------------
6
+ Qo 142.416k (± 4.3%) i/s - 716.416k in 5.040430s
7
+ Fear 88.179k (± 4.8%) i/s - 444.665k in 5.055908s
8
+
9
+ Comparison:
10
+ Qo: 142415.6 i/s
11
+ Fear: 88179.5 i/s - 1.62x slower
@@ -0,0 +1,11 @@
1
+ > bundle exec rake perf:pattern_matching:qo_vs_fear_try_execution
2
+ Warming up --------------------------------------
3
+ Qo 10.079k i/100ms
4
+ Fear 25.868k i/100ms
5
+ Calculating -------------------------------------
6
+ Qo 142.209k (± 3.8%) i/s - 715.609k in 5.039975s
7
+ Fear 395.999k (± 2.5%) i/s - 1.992M in 5.033046s
8
+
9
+ Comparison:
10
+ Fear: 395999.2 i/s
11
+ Qo: 142209.4 i/s - 2.78x slower
@@ -0,0 +1,15 @@
1
+ require 'fear'
2
+
3
+ User = Struct.new(:id, :name, :admin)
4
+
5
+ matcher = Fear.matcher do |m|
6
+ m.xcase('User(_, name, true)') do |name:|
7
+ puts "Hi #{name}, you are welcome"
8
+ end
9
+ m.xcase('User(_, _, false)') do
10
+ puts 'Only admins allowed here'
11
+ end
12
+ end
13
+
14
+ matcher.call User.new(1, 'Jane', true)
15
+ matcher.call User.new(1, 'John', false)
@@ -0,0 +1,96 @@
1
+ require 'fear'
2
+
3
+ # @example Usage
4
+ # set = BinaryTreeSet.new
5
+ # set.add(4)
6
+ # set.includes?(4) #=> true
7
+ # set.includes?(5) #=> false
8
+ # set.delete(4)
9
+ # set.includes?(4) #=> false
10
+ #
11
+ class BinaryTreeSet
12
+ Position = Module.new
13
+ Right = Module.new.include(Position)
14
+ Left = Module.new.include(Position)
15
+
16
+ def initialize(elem = 0, removed: true)
17
+ @elem = elem
18
+ @removed = removed
19
+ @subtrees = {}
20
+ end
21
+ attr_reader :elem, :subtrees
22
+ attr_accessor :removed
23
+ private :elem
24
+ private :removed
25
+ private :subtrees
26
+
27
+ # @param value [Integer]
28
+ # @return [Boolean]
29
+ def includes?(value)
30
+ Fear.match(value) do |m|
31
+ m.case(elem) { !removed }
32
+ m.case(->(x) { x > elem }) { |v| includes_in_leaf?(Right, v) }
33
+ m.case(->(x) { x < elem }) { |v| includes_in_leaf?(Left, v) }
34
+ end
35
+ end
36
+
37
+ # @param position [Position]
38
+ # @param value [Integer]
39
+ # @return [Boolean]
40
+ private def includes_in_leaf?(position, value)
41
+ leaf(position).match do |m|
42
+ m.some { |leaf| leaf.includes?(value) }
43
+ m.none { false }
44
+ end
45
+ end
46
+
47
+ # @param value [Integer]
48
+ # @return [void]
49
+ def add(value)
50
+ Fear.match(value) do |m|
51
+ m.case(elem) { self.removed = false }
52
+ m.case(->(x) { x > elem }) { |v| add_to_leaf(Right, v) }
53
+ m.case(->(x) { x < elem }) { |v| add_to_leaf(Left, v) }
54
+ end
55
+ end
56
+
57
+ # @param position [Position]
58
+ # @param value [Integer]
59
+ # @return [void]
60
+ private def add_to_leaf(position, value)
61
+ leaf(position).match do |m|
62
+ m.some { |leaf| leaf.add(value) }
63
+ m.none { subtrees[position] = BinaryTreeSet.new(value, removed: false) }
64
+ end
65
+ end
66
+
67
+ # @param value [Integer]
68
+ # @return [void]
69
+ def delete(value)
70
+ Fear.match(value) do |m|
71
+ m.case(elem) { self.removed = true }
72
+ m.case(->(x) { x > elem }) { |v| delete_from_leaf(Right, v) }
73
+ m.case(->(x) { x < elem }) { |v| delete_from_leaf(Left, v) }
74
+ end
75
+ end
76
+
77
+ # @param position [Position]
78
+ # @param value [Integer]
79
+ # @return [void]
80
+ private def delete_from_leaf(position, value)
81
+ leaf(position).match do |m|
82
+ m.some { |leaf| leaf.delete(value) }
83
+ m.none { subtrees[position] = BinaryTreeSet.new(value, removed: true) }
84
+ end
85
+ end
86
+
87
+ # @param position [Position]
88
+ # @return [Fear::Option<BinaryTreeSet>]
89
+ private def leaf(position)
90
+ if subtrees.key?(position)
91
+ Fear.some(subtrees[position])
92
+ else
93
+ Fear.none
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,54 @@
1
+ require 'fear'
2
+
3
+ class ToWords
4
+ CONVERTER = Fear.matcher do |m|
5
+ {
6
+ 0 => 'zero',
7
+ 1 => 'one',
8
+ 2 => 'two',
9
+ 3 => 'three',
10
+ 4 => 'four',
11
+ 5 => 'five',
12
+ 6 => 'six',
13
+ 7 => 'seven',
14
+ 8 => 'eight',
15
+ 9 => 'nine',
16
+ 10 => 'ten',
17
+ 11 => 'eleven',
18
+ 12 => 'twelve',
19
+ 13 => 'thirteen',
20
+ 14 => 'fourteen',
21
+ 15 => 'fifteen',
22
+ 16 => 'sixteen',
23
+ 17 => 'seventeen',
24
+ 18 => 'eighteen',
25
+ 19 => 'nineteen',
26
+ 20 => 'twenty',
27
+ 30 => 'thirty',
28
+ 40 => 'forty',
29
+ 50 => 'fifty',
30
+ 60 => 'sixty',
31
+ 70 => 'seventy',
32
+ 80 => 'eighty',
33
+ 90 => 'ninety',
34
+ }.each_pair do |number, in_words|
35
+ m.case(number) { in_words }
36
+ end
37
+ m.case(->(n) { n < 0 }) { |n| "minus #{CONVERTER.call(-n)}" }
38
+ m.case(->(n) { n < 100 }) { |n| "#{CONVERTER.call((n / 10) * 10)}-#{CONVERTER.call(n % 10)}" }
39
+ m.case(->(n) { n < 200 }) { |n| "one hundred #{CONVERTER.call(n % 100)}" }
40
+ m.case(->(n) { n < 1_000 }) { |n| "#{CONVERTER.call(n / 100)} hundreds #{CONVERTER.call(n % 100)}" }
41
+ m.case(->(n) { n < 2_000 }) { |n| "one thousand #{CONVERTER.call(n % 1000)}" }
42
+ m.case(->(n) { n < 1_000_000 }) { |n| "#{CONVERTER.call(n / 1_000)} thousands #{CONVERTER.call(n % 1_000)}" }
43
+ m.else { |n| raise "#{n} too big " }
44
+ end
45
+
46
+ def self.call(number)
47
+ Fear.case(Integer, &:itself).and_then(CONVERTER).call(number)
48
+ end
49
+ end
50
+
51
+ ToWords.call(99) #=> 'ninety-nine'
52
+ ToWords.call(133) #=> 'one hundred thirty-three
53
+ ToWords.call(777) #=> 'seven hundreds seventy-seven'
54
+ ToWords.call(254_555) #=> 'two hundreds fifty-four thousands five hundreds fifty-five'
@@ -24,12 +24,14 @@ Gem::Specification.new do |spec|
24
24
  Successfully installed fear-#{Fear::VERSION}
25
25
  MSG
26
26
 
27
- spec.add_runtime_dependency 'dry-equalizer', '<= 0.2.1'
27
+ spec.add_runtime_dependency 'lru_redux'
28
+ spec.add_runtime_dependency 'treetop'
28
29
 
29
- spec.add_development_dependency 'appraisal'
30
30
  spec.add_development_dependency 'benchmark-ips'
31
31
  spec.add_development_dependency 'bundler'
32
+ spec.add_development_dependency 'concurrent-ruby'
32
33
  spec.add_development_dependency 'dry-matcher'
34
+ spec.add_development_dependency 'dry-monads'
33
35
  spec.add_development_dependency 'qo'
34
36
  spec.add_development_dependency 'rake', '~> 10.0'
35
37
  spec.add_development_dependency 'rspec', '~> 3.1'
@@ -1,19 +1,34 @@
1
- require 'dry-equalizer'
2
- require 'fear/version'
1
+ require 'fear/either_api'
2
+ require 'fear/extractor_api'
3
+ require 'fear/for_api'
4
+ require 'fear/future_api'
5
+ require 'fear/option_api'
3
6
  require 'fear/pattern_matching_api'
7
+ require 'fear/try_api'
8
+ require 'fear/version'
4
9
 
5
10
  module Fear
6
11
  Error = Class.new(StandardError)
7
- NoSuchElementError = Class.new(Error)
12
+ IllegalStateException = Class.new(Error)
8
13
  MatchError = Class.new(Error)
14
+ NoSuchElementError = Class.new(Error)
15
+ PatternSyntaxError = Class.new(Error)
16
+
17
+ extend EitherApi
18
+ extend ExtractorApi
19
+ extend ForApi
20
+ extend FutureApi
21
+ extend OptionApi
9
22
  extend PatternMatchingApi
23
+ extend TryApi
10
24
 
11
25
  autoload :EmptyPartialFunction, 'fear/empty_partial_function'
12
26
  autoload :PartialFunction, 'fear/partial_function'
13
27
  autoload :PartialFunctionClass, 'fear/partial_function_class'
14
28
  autoload :PatternMatch, 'fear/pattern_match'
29
+ autoload :Extractor, 'fear/extractor'
15
30
 
16
- autoload :Done, 'fear/done'
31
+ autoload :Unit, 'fear/unit'
17
32
  autoload :For, 'fear/for'
18
33
  autoload :RightBiased, 'fear/right_biased'
19
34
  autoload :Utils, 'fear/utils'
@@ -40,6 +55,8 @@ module Fear
40
55
  autoload :Right, 'fear/right'
41
56
  autoload :RightPatternMatch, 'fear/right_pattern_match'
42
57
 
58
+ autoload :Future, 'fear/future'
59
+
43
60
  module Mixin
44
61
  include Either::Mixin
45
62
  include For::Mixin
@@ -14,9 +14,9 @@ module Fear
14
14
  # @example
15
15
  # in = Readline.readline('Type Either a string or an Int: ', true)
16
16
  # result = begin
17
- # Right(Integer(in))
17
+ # Fear.right(Integer(in))
18
18
  # rescue ArgumentError
19
- # Left(in)
19
+ # Fear.left(in)
20
20
  # end
21
21
  #
22
22
  # result.match do |m|
@@ -40,21 +40,21 @@ module Fear
40
40
  # @yieldreturn [any]
41
41
  # @return [any]
42
42
  # @example
43
- # Right(42).get_or_else { 24/2 } #=> 42
44
- # Left('undefined').get_or_else { 24/2 } #=> 12
43
+ # Fear.right(42).get_or_else { 24/2 } #=> 42
44
+ # Fear.left('undefined').get_or_else { 24/2 } #=> 12
45
45
  # @overload get_or_else(default)
46
46
  # @return [any]
47
47
  # @example
48
- # Right(42).get_or_else(12) #=> 42
49
- # Left('undefined').get_or_else(12) #=> 12
48
+ # Fear.right(42).get_or_else(12) #=> 42
49
+ # Fear.left('undefined').get_or_else(12) #=> 12
50
50
  #
51
51
  # @!method or_else(&alternative)
52
52
  # Returns this +Right+ or the given alternative if this is a +Left+.
53
53
  # @return [Either]
54
54
  # @example
55
- # Right(42).or_else { Right(21) } #=> Right(42)
56
- # Left('unknown').or_else { Right(21) } #=> Right(21)
57
- # Left('unknown').or_else { Left('empty') } #=> Left('empty')
55
+ # Fear.right(42).or_else { Fear.right(21) } #=> Fear.right(42)
56
+ # Fear.left('unknown').or_else { Fear.right(21) } #=> Fear.right(21)
57
+ # Fear.left('unknown').or_else { Fear.left('empty') } #=> Fear.left('empty')
58
58
  #
59
59
  # @!method include?(other_value)
60
60
  # Returns +true+ if +Right+ has an element that is equal
@@ -62,9 +62,9 @@ module Fear
62
62
  # @param [any]
63
63
  # @return [Boolean]
64
64
  # @example
65
- # Right(17).include?(17) #=> true
66
- # Right(17).include?(7) #=> false
67
- # Left('undefined').include?(17) #=> false
65
+ # Fear.right(17).include?(17) #=> true
66
+ # Fear.right(17).include?(7) #=> false
67
+ # Fear.left('undefined').include?(17) #=> false
68
68
  #
69
69
  # @!method each(&block)
70
70
  # Performs the given block if this is a +Right+.
@@ -72,11 +72,11 @@ module Fear
72
72
  # @yieldreturn [void]
73
73
  # @return [Option] itself
74
74
  # @example
75
- # Right(17).each do |value|
75
+ # Fear.right(17).each do |value|
76
76
  # puts value
77
77
  # end #=> prints 17
78
78
  #
79
- # Left('undefined').each do |value|
79
+ # Fear.left('undefined').each do |value|
80
80
  # puts value
81
81
  # end #=> does nothing
82
82
  #
@@ -86,8 +86,8 @@ module Fear
86
86
  # @yieldparam [any] value
87
87
  # @yieldreturn [any]
88
88
  # @example
89
- # Right(42).map { |v| v/2 } #=> Right(21)
90
- # Left('undefined').map { |v| v/2 } #=> Left('undefined')
89
+ # Fear.right(42).map { |v| v/2 } #=> Fear.right(21)
90
+ # Fear.left('undefined').map { |v| v/2 } #=> Fear.left('undefined')
91
91
  #
92
92
  # @!method flat_map(&block)
93
93
  # Returns the given block applied to the value from this +Right+
@@ -96,16 +96,16 @@ module Fear
96
96
  # @yieldreturn [Option]
97
97
  # @return [Option]
98
98
  # @example
99
- # Right(42).flat_map { |v| Right(v/2) } #=> Right(21)
100
- # Left('undefined').flat_map { |v| Right(v/2) } #=> Left('undefined')
99
+ # Fear.right(42).flat_map { |v| Fear.right(v/2) } #=> Fear.right(21)
100
+ # Fear.left('undefined').flat_map { |v| Fear.right(v/2) } #=> Fear.left('undefined')
101
101
  #
102
102
  # @!method to_option
103
103
  # Returns an +Some+ containing the +Right+ value or a +None+ if
104
104
  # this is a +Left+.
105
105
  # @return [Option]
106
106
  # @example
107
- # Right(42).to_option #=> Some(21)
108
- # Left('undefined').to_option #=> None()
107
+ # Fear.right(42).to_option #=> Fear.some(21)
108
+ # Fear.left('undefined').to_option #=> Fear.none()
109
109
  #
110
110
  # @!method any?(&predicate)
111
111
  # Returns +false+ if +Left+ or returns the result of the
@@ -114,9 +114,9 @@ module Fear
114
114
  # @yieldreturn [Boolean]
115
115
  # @return [Boolean]
116
116
  # @example
117
- # Right(12).any?( |v| v > 10) #=> true
118
- # Right(7).any?( |v| v > 10) #=> false
119
- # Left('undefined').any?( |v| v > 10) #=> false
117
+ # Fear.right(12).any?( |v| v > 10) #=> true
118
+ # Fear.right(7).any?( |v| v > 10) #=> false
119
+ # Fear.left('undefined').any?( |v| v > 10) #=> false
120
120
  #
121
121
  # -----
122
122
  #
@@ -125,16 +125,16 @@ module Fear
125
125
  # @note this method is also aliased as +#success?+
126
126
  # @return [Boolean]
127
127
  # @example
128
- # Right(42).right? #=> true
129
- # Left('err').right? #=> false
128
+ # Fear.right(42).right? #=> true
129
+ # Fear.left('err').right? #=> false
130
130
  #
131
131
  # @!method left?
132
132
  # Returns +true+ if this is a +Left+, +false+ otherwise.
133
133
  # @note this method is also aliased as +#failure?+
134
134
  # @return [Boolean]
135
135
  # @example
136
- # Right(42).left? #=> false
137
- # Left('err').left? #=> true
136
+ # Fear.right(42).left? #=> false
137
+ # Fear.left('err').left? #=> true
138
138
  #
139
139
  # @!method select_or_else(default, &predicate)
140
140
  # Returns +Left+ of the default if the given predicate
@@ -144,10 +144,10 @@ module Fear
144
144
  # @yieldreturn [Boolean]
145
145
  # @return [Either]
146
146
  # @example
147
- # Right(12).select_or_else(-1, &:even?) #=> Right(12)
148
- # Right(7).select_or_else(-1, &:even?) #=> Left(-1)
149
- # Left(12).select_or_else(-1, &:even?) #=> Left(12)
150
- # Left(12).select_or_else(-> { -1 }, &:even?) #=> Left(12)
147
+ # Fear.right(12).select_or_else(-1, &:even?) #=> Fear.right(12)
148
+ # Fear.right(7).select_or_else(-1, &:even?) #=> Fear.left(-1)
149
+ # Fear.left(12).select_or_else(-1, &:even?) #=> Fear.left(12)
150
+ # Fear.left(12).select_or_else(-> { -1 }, &:even?) #=> Fear.left(12)
151
151
  #
152
152
  # @!method select(&predicate)
153
153
  # Returns +Left+ of value if the given predicate
@@ -156,10 +156,10 @@ module Fear
156
156
  # @yieldreturn [Boolean]
157
157
  # @return [Either]
158
158
  # @example
159
- # Right(12).select(&:even?) #=> Right(12)
160
- # Right(7).select(&:even?) #=> Left(7)
161
- # Left(12).select(&:even?) #=> Left(12)
162
- # Left(7).select(&:even?) #=> Left(7)
159
+ # Fear.right(12).select(&:even?) #=> Fear.right(12)
160
+ # Fear.right(7).select(&:even?) #=> Fear.left(7)
161
+ # Fear.left(12).select(&:even?) #=> Fear.left(12)
162
+ # Fear.left(7).select(&:even?) #=> Fear.left(7)
163
163
  #
164
164
  # @!method reject(&predicate)
165
165
  # Returns +Left+ of value if the given predicate holds for the
@@ -168,17 +168,17 @@ module Fear
168
168
  # @yieldreturn [Boolean]
169
169
  # @return [Either]
170
170
  # @example
171
- # Right(12).reject(&:even?) #=> Left(12)
172
- # Right(7).reject(&:even?) #=> Right(7)
173
- # Left(12).reject(&:even?) #=> Left(12)
174
- # Left(7).reject(&:even?) #=> Left(7)
171
+ # Fear.right(12).reject(&:even?) #=> Fear.left(12)
172
+ # Fear.right(7).reject(&:even?) #=> Fear.right(7)
173
+ # Fear.left(12).reject(&:even?) #=> Fear.left(12)
174
+ # Fear.left(7).reject(&:even?) #=> Fear.left(7)
175
175
  #
176
176
  # @!method swap
177
177
  # If this is a +Left+, then return the left value in +Right+ or vice versa.
178
178
  # @return [Either]
179
179
  # @example
180
- # Left('left').swap #=> Right('left')
181
- # Right('right').swap #=> Light('left')
180
+ # Fear.left('left').swap #=> Fear.right('left')
181
+ # Fear.right('right').swap #=> Fear.left('left')
182
182
  #
183
183
  # @!method reduce(reduce_left, reduce_right)
184
184
  # Applies +reduce_left+ if this is a +Left+ or +reduce_right+ if
@@ -204,10 +204,10 @@ module Fear
204
204
  # @return [Either]
205
205
  # @raise [TypeError] if it does not contain +Either+.
206
206
  # @example
207
- # Right(Right(12)).join_right #=> Right(12)
208
- # Right(Left("flower")).join_right #=> Left("flower")
209
- # Left("flower").join_right #=> Left("flower")
210
- # Left(Right("flower")).join_right #=> Left(Right("flower"))
207
+ # Fear.right(Fear.right(12)).join_right #=> Fear.right(12)
208
+ # Fear.right(Fear.left("flower")).join_right #=> Fear.left("flower")
209
+ # Fear.left("flower").join_right #=> Fear.left("flower")
210
+ # Fear.left(Fear.right("flower")).join_right #=> Fear.left(Fear.right("flower"))
211
211
  #
212
212
  # @!method join_right
213
213
  # Joins an +Either+ through +Left+. This method requires
@@ -217,16 +217,16 @@ module Fear
217
217
  # @return [Either]
218
218
  # @raise [TypeError] if it does not contain +Either+.
219
219
  # @example
220
- # Left(Right("flower")).join_left #=> Right("flower")
221
- # Left(Left(12)).join_left #=> Left(12)
222
- # Right("daisy").join_left #=> Right("daisy")
223
- # Right(Left("daisy")).join_left #=> Right(Left("daisy"))
220
+ # Fear.left(Fear.right("flower")).join_left #=> Fear.right("flower")
221
+ # Fear.left(Fear.left(12)).join_left #=> Fear.left(12)
222
+ # Fear.right("daisy").join_left #=> Fear.right("daisy")
223
+ # Fear.right(Fear.left("daisy")).join_left #=> Fear.right(Fear.left("daisy"))
224
224
  #
225
225
  # @!method match(&matcher)
226
226
  # Pattern match against this +Either+
227
227
  # @yield matcher [Fear::EitherPatternMatch]
228
228
  # @example
229
- # Either(val).match do |m|
229
+ # either.match do |m|
230
230
  # m.right(Integer) do |x|
231
231
  # x * 2
232
232
  # end
@@ -242,8 +242,6 @@ module Fear
242
242
  # @see https://github.com/scala/scala/blob/2.12.x/src/library/scala/util/Either.scala
243
243
  #
244
244
  module Either
245
- include Dry::Equalizer(:value)
246
-
247
245
  # @private
248
246
  def left_class
249
247
  Left
@@ -261,6 +259,20 @@ module Fear
261
259
  attr_reader :value
262
260
  protected :value
263
261
 
262
+ # @param other [Any]
263
+ # @return [Boolean]
264
+ def ==(other)
265
+ other.is_a?(self.class) && value == other.value
266
+ end
267
+
268
+ # @return [String]
269
+ def inspect
270
+ "#<#{self.class} value=#{value.inspect}>"
271
+ end
272
+
273
+ # @return [String]
274
+ alias to_s inspect
275
+
264
276
  class << self
265
277
  # Build pattern matcher to be used later, despite off
266
278
  # +Either#match+ method, id doesn't apply matcher immanently,
@@ -275,7 +287,7 @@ module Fear
275
287
  # m.left(String) { :err }
276
288
  # m.else { 'error '}
277
289
  # end
278
- # matcher.call(Some(42))
290
+ # matcher.call(Fear.right(42))
279
291
  #
280
292
  # @yieldparam [Fear::EitherPatternMatch]
281
293
  # @return [Fear::PartialFunction]
@@ -292,16 +304,22 @@ module Fear
292
304
  # Left('beaf') #=> #<Fear::Legt value='beaf'>
293
305
  #
294
306
  module Mixin
295
- # @param [any]
296
- # @return [Left]
307
+ # @param value [any]
308
+ # @return [Fear::Left]
309
+ # @example
310
+ # Left(42) #=> #<Fear::Left value=42>
311
+ #
297
312
  def Left(value)
298
- Left.new(value)
313
+ Fear.left(value)
299
314
  end
300
315
 
301
- # @param [any]
302
- # @return [Right]
316
+ # @param value [any]
317
+ # @return [Fear::Right]
318
+ # @example
319
+ # Right(42) #=> #<Fear::Right value=42>
320
+ #
303
321
  def Right(value)
304
- Right.new(value)
322
+ Fear.right(value)
305
323
  end
306
324
  end
307
325
  end