fear 0.11.0 → 1.0.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.
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