ramda-ruby 0.12.0 → 0.14.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.
@@ -0,0 +1,48 @@
1
+ # module Ramda
2
+ # module Internal
3
+ # module Integrations
4
+ # module Comparable
5
+ # def ===(other)
6
+ # specifications.find(&other.method(:respond_to?))
7
+ # end
8
+ # end
9
+ #
10
+ # class DryMonadsType
11
+ # extend Comparable
12
+ #
13
+ # def self.specifications
14
+ # @specifications ||= [
15
+ # :bind,
16
+ # :fmap,
17
+ # :pure,
18
+ # ]
19
+ # end
20
+ # end
21
+ #
22
+ # class RamdaFantasyRubyType
23
+ # extend Comparable
24
+ #
25
+ # def self.specifications
26
+ # @specifications ||= [
27
+ # :ap,
28
+ # :chain,
29
+ # :map,
30
+ # :of
31
+ # ]
32
+ # end
33
+ # end
34
+ #
35
+ # class KleisliType
36
+ # extend Comparable
37
+ #
38
+ # def self.specifications
39
+ # @specifications ||= [
40
+ # :'>->',
41
+ # :*,
42
+ # :fmap
43
+ # ]
44
+ # end
45
+ # end
46
+ # end
47
+ # end
48
+ # end
@@ -5,36 +5,7 @@ module Ramda
5
5
  # Signature: (*, reducing_fn) -> Proc((acc, input) -> acc)
6
6
  #
7
7
  module Transducers
8
- # predicate - fn with 1 arity
9
- def self.filter(predicate, reducer)
10
- lambda do |acc, x|
11
- if predicate.call(x)
12
- reducer.call(acc, x)
13
- else
14
- acc
15
- end
16
- end
17
- end
18
-
19
- # transformer - fn with 1 arity
20
- def self.map(transformer, reducer)
21
- lambda do |acc, x|
22
- reducer.call(acc, transformer.call(x))
23
- end
24
- end
25
-
26
- # limit - number
27
- def self.take(limit, reducer)
28
- count = 0
29
- lambda do |acc, x|
30
- count += 1
31
- if limit >= count
32
- reducer.call(acc, x)
33
- else
34
- acc
35
- end
36
- end
37
- end
8
+ Dir["#{File.dirname(__FILE__)}/transducers/*"].each { |file| require file }
38
9
  end
39
10
  end
40
11
  end
@@ -0,0 +1,19 @@
1
+ module Ramda
2
+ module Internal
3
+ module Transducers
4
+ # Removes repeats from list
5
+ class DropRepeatsTransducer
6
+ # No arguments
7
+ def call(reducer)
8
+ lambda do |acc, x|
9
+ if acc.any? && acc.last == x
10
+ acc
11
+ else
12
+ reducer.call(acc, x)
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ module Ramda
2
+ module Internal
3
+ module Transducers
4
+ # Remove repeats with based on predicate which receives a, b
5
+ class DropRepeatsWithTransducer
6
+ # predicate - fn with 2 arity
7
+ def call(predicate, reducer)
8
+ lambda do |acc, x|
9
+ if acc.any? && predicate.call(acc.last, x)
10
+ acc
11
+ else
12
+ reducer.call(acc, x)
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ module Ramda
2
+ module Internal
3
+ module Transducers
4
+ # Filter list based on predicate which receives x
5
+ class FilterTransducer
6
+ # predicate - fn with 1 arity
7
+ def call(predicate, reducer)
8
+ lambda do |acc, x|
9
+ if predicate.call(x)
10
+ reducer.call(acc, x)
11
+ else
12
+ acc
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,15 @@
1
+ module Ramda
2
+ module Internal
3
+ module Transducers
4
+ # Transform collection based on transformer
5
+ class MapTransducer
6
+ # transformer - fn with 1 arity
7
+ def call(transformer, reducer)
8
+ lambda do |acc, x|
9
+ reducer.call(acc, transformer.call(x))
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,21 @@
1
+ module Ramda
2
+ module Internal
3
+ module Transducers
4
+ # Returns a head of collection
5
+ class TakeTransducer
6
+ # limit - number
7
+ def call(limit, reducer)
8
+ count = 0
9
+ lambda do |acc, x|
10
+ count += 1
11
+ if limit >= count
12
+ reducer.call(acc, x)
13
+ else
14
+ acc
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -6,11 +6,21 @@ module Ramda
6
6
  # List functions
7
7
  # rubocop:disable Metrics/ModuleLength
8
8
  module List
9
- Transducer = ->(method) { ::Ramda::Internal::Transducers.method(method) }
10
-
11
9
  extend ::Ramda::Internal::CurriedMethod
12
10
  extend ::Ramda::Internal::Dispatchable
13
11
 
12
+ Trans = ::Ramda::Internal::Transducers
13
+
14
+ # Applies a function to the value at the given index of an array,
15
+ # returning a new copy of the array with the element at the given
16
+ # index replaced with the result of the function application.
17
+ #
18
+ # (a -> a) -> Number -> [a] -> [a]
19
+ #
20
+ curried_method(:adjust) do |f, idx, xs|
21
+ xs.dup.tap { |a| a[idx] = f.call(a[idx]) }
22
+ end
23
+
14
24
  # Returns true if all elements of the list match the predicate,
15
25
  # false if there are any that don't.
16
26
  #
@@ -65,7 +75,7 @@ module Ramda
65
75
  #
66
76
  # Chain m => (a -> m b) -> m a -> m b
67
77
  #
68
- curried(:chain, &dispatchable([:chain, :bind], ::Array) do |f, xs|
78
+ curried(:chain, &dispatchable([:chain, :bind, :'>'], ::Array) do |f, xs|
69
79
  xs.flat_map(&f)
70
80
  end)
71
81
 
@@ -105,6 +115,34 @@ module Ramda
105
115
  xs[num..-1] || xs.class.new
106
116
  end)
107
117
 
118
+ # Returns a new list without any consecutively repeating elements.
119
+ # R.equals is used to determine equality.
120
+ #
121
+ # Acts as a transducer if a transformer is given in list position.
122
+ #
123
+ # [a] -> [a]
124
+ #
125
+ curried_method(:drop_repeats,
126
+ &dispatchable1([], ::Array, Trans::DropRepeatsTransducer.new) do |xs|
127
+ xs.chunk { |n| n }.map(&:first)
128
+ end)
129
+
130
+ # Returns a new list without any consecutively repeating elements.
131
+ # Equality is determined by applying the supplied predicate to each
132
+ # pair of consecutive elements.
133
+ # The first element in a series of equal elements will be preserved.
134
+ #
135
+ # Acts as a transducer if a transformer is given in list position.
136
+ #
137
+ # (a, a -> Boolean) -> [a] -> [a]
138
+ #
139
+ curried_method(:drop_repeats_with,
140
+ &dispatchable([], [::Array], Trans::DropRepeatsWithTransducer.new) do |f, xs|
141
+ xs.each_with_object([]) do |a, acc|
142
+ acc.push(a) unless acc.any? && f.call(acc.last, a)
143
+ end
144
+ end)
145
+
108
146
  # Returns a new list excluding the leading elements of a given list which
109
147
  # satisfy the supplied predicate function. It passes each value to the
110
148
  # supplied predicate function, skipping elements while the predicate
@@ -130,13 +168,14 @@ module Ramda
130
168
  #
131
169
  # Filterable f => (a -> Boolean) -> f a -> f a
132
170
  #
133
- curried(:filter, &dispatchable(:filter, [::Array, ::Hash], Transducer[:filter]) do |f, xs|
134
- if xs.is_a?(Hash)
135
- xs.select { |_, value| f.call(value) }
136
- else
137
- xs.select(&f)
138
- end
139
- end)
171
+ curried(:filter,
172
+ &dispatchable(:filter, [::Array, ::Hash], Trans::FilterTransducer.new) do |f, xs|
173
+ if xs.is_a?(Hash)
174
+ xs.select { |_, value| f.call(value) }
175
+ else
176
+ xs.select(&f)
177
+ end
178
+ end)
140
179
 
141
180
  # Creates a new object from a list key-value pairs. If a key appears in
142
181
  # multiple pairs, the rightmost pair is included in the object.
@@ -270,6 +309,19 @@ module Ramda
270
309
  xs.dup.insert(index, *elts)
271
310
  end
272
311
 
312
+ # Creates a new list with the separator interposed between elements.
313
+ #
314
+ # Dispatches to the intersperse method of the second argument, if present.
315
+ #
316
+ # a -> [a] -> [a]
317
+ #
318
+ curried_method(:intersperse, &dispatchable([:intersperse], ::Array) do |sep, xs|
319
+ xs.reduce([]) do |acc, a|
320
+ acc << sep if acc.any?
321
+ acc << a
322
+ end
323
+ end)
324
+
273
325
  # Transforms the items of the list with the transducer and appends
274
326
  # the transformed items to the accumulator using an appropriate iterator
275
327
  # function based on the accumulator type.
@@ -293,16 +345,13 @@ module Ramda
293
345
  curried_method(:into) do |acc, xf, xs|
294
346
  rx = case acc
295
347
  when ::Array
296
- lambda { |arr, x|
297
- arr.push(x)
298
- arr
299
- }
348
+ ->(arr, x) { arr << x }
300
349
  when ::String
301
350
  ->(str, x) { "#{str}#{x}" }
302
351
  when ::Object
303
352
  ->(obj, x) { obj.merge(x) }
304
353
  else
305
- raise ArgumetError, "Cannot create transformer for #{acc}"
354
+ raise ArgumetError, "Cannot create default transformer for #{acc}"
306
355
  end
307
356
  xs.reduce(acc, &xf.call(rx))
308
357
  end
@@ -349,14 +398,15 @@ module Ramda
349
398
  #
350
399
  # Functor f => (a -> b) -> f a -> f b
351
400
  #
352
- curried(:map, &dispatchable(:map, [::Hash, ::Array], Transducer[:map]) do |f, xs|
353
- case xs
354
- when ::Hash
355
- Hash[xs.map { |k, v| [k, f.call(v)] }]
356
- when ::Array
357
- xs.map(&f)
358
- end
359
- end)
401
+ curried(:map,
402
+ &dispatchable([:map, :fmap], [::Hash, ::Array], Trans::MapTransducer.new) do |f, xs|
403
+ case xs
404
+ when ::Hash
405
+ Hash[xs.map { |k, v| [k, f.call(v)] }]
406
+ when ::Array
407
+ xs.map(&f)
408
+ end
409
+ end)
360
410
 
361
411
  # The mapAccum function behaves like a combination of map and reduce;
362
412
  # it applies a function to each element of a list, passing
@@ -426,7 +476,7 @@ module Ramda
426
476
  # Functor f => k -> f {k: v} -> f v
427
477
  #
428
478
  curried_method(:pluck) do |key, xs|
429
- xs.map { |x| x[key] }
479
+ Ramda.map(->(x) { x[key] }, xs)
430
480
  end
431
481
 
432
482
  # Returns a new list with the given element at the front, followed by the
@@ -557,9 +607,10 @@ module Ramda
557
607
  # Number -> [a] -> [a]
558
608
  # Number -> String -> String
559
609
  #
560
- curried(:take, &dispatchable(:take, [::Array, ::String], Transducer[:take]) do |num, xs|
561
- xs[0, num]
562
- end)
610
+ curried(:take,
611
+ &dispatchable(:take, [::Array, ::String], Trans::TakeTransducer.new) do |num, xs|
612
+ xs[0, num]
613
+ end)
563
614
 
564
615
  # Returns a new list containing the first n elements of a given list,
565
616
  # passing each value to the supplied predicate function, and terminating
@@ -51,7 +51,11 @@ module Ramda
51
51
  # (*... -> Boolean) -> (*... -> Boolean) -> (*... -> Boolean)
52
52
  #
53
53
  curried_method(:both) do |fa, fb|
54
- ->(*args) { fa.call(*args) && fb.call(*args) }
54
+ if fa.is_a?(Proc)
55
+ ->(*args) { fa.call(*args) && fb.call(*args) }
56
+ else
57
+ Ramda.lift(Ramda.and, fa, fb)
58
+ end
55
59
  end
56
60
 
57
61
  # Takes a function f and returns a function g such that if called with
@@ -63,9 +67,13 @@ module Ramda
63
67
  # (*... -> *) -> (*... -> Boolean)
64
68
  #
65
69
  curried_method(:complement) do |fn|
66
- ::Ramda::Internal::FunctionWithArity.call(fn.arity) do |*args|
67
- !fn.call(*args)
68
- end.curry
70
+ if fn.is_a?(Proc)
71
+ ::Ramda::Internal::FunctionWithArity.call(fn.arity) do |*args|
72
+ !fn.call(*args)
73
+ end.curry
74
+ else
75
+ Ramda.lift(Ramda.not, fn)
76
+ end
69
77
  end
70
78
 
71
79
  # Returns a function, fn, which encapsulates if/else, if/else, ...
@@ -105,7 +113,11 @@ module Ramda
105
113
  # (*... -> Boolean) -> (*... -> Boolean) -> (*... -> Boolean))
106
114
  #
107
115
  curried_method(:either) do |fa, fb|
108
- ->(*args) { fa.call(*args) || fb.call(*args) }
116
+ if fa.is_a?(Proc)
117
+ ->(*args) { fa.call(*args) || fb.call(*args) }
118
+ else
119
+ ::Ramda.lift(Ramda.or, fa, fb)
120
+ end
109
121
  end
110
122
 
111
123
  # Creates a function that will process either the onTrue or the onFalse
@@ -26,7 +26,7 @@ module Ramda
26
26
  # Number -> Number -> Number
27
27
  #
28
28
  curried_method(:divide) do |a, b|
29
- a.to_f / b
29
+ a.fdiv(b)
30
30
  end
31
31
 
32
32
  # Increments its argument.
@@ -43,6 +43,37 @@ module Ramda
43
43
  # return ((m % p) + p) % p;
44
44
  end
45
45
 
46
+ # Returns the mean of the given list of numbers.
47
+ #
48
+ # [Number] -> Number
49
+ #
50
+ curried_method(:mean) do |xs|
51
+ size = xs.size
52
+
53
+ if size.zero?
54
+ Float::NAN
55
+ else
56
+ xs.reduce(&:+).fdiv(size)
57
+ end
58
+ end
59
+
60
+ # Returns the median of the given list of numbers.
61
+ #
62
+ # [Number] -> Number
63
+ #
64
+ curried_method(:median) do |xs|
65
+ sorted = xs.sort
66
+ size = sorted.size
67
+
68
+ if size.zero?
69
+ Float::NAN
70
+ elsif size.odd?
71
+ sorted[size / 2]
72
+ else
73
+ sorted[size / 2 - 1, 2].reduce(&:+).fdiv(2)
74
+ end
75
+ end
76
+
46
77
  # Divides the first parameter by the second and returns the remainder.
47
78
  #
48
79
  # Number -> Number -> Number