Class: Funcify::Fn

Inherits:
Object
  • Object
show all
Extended by:
Dry::Monads::Result::Mixin, Dry::Monads::Try::Mixin
Defined in:
lib/funcify/fn.rb

Class Method Summary collapse

Class Method Details

.addObject

add an element to an array



42
43
44
# File 'lib/funcify/fn.rb', line 42

def add
  -> x, xs { xs << x }.curry
end

.all?Boolean

Returns:

  • (Boolean)


71
72
73
# File 'lib/funcify/fn.rb', line 71

def all?
  ->(f, enum) { enum.all? { |e| f.(e) } }.curry
end

.all_keysObject



239
240
241
# File 'lib/funcify/fn.rb', line 239

def all_keys
  -> h { h.flat_map { |k, v| [k] + (v.is_a?(Hash) ? all_keys.(v) : [v]) } }
end

.all_success?Boolean

Returns:

  • (Boolean)


357
358
359
# File 'lib/funcify/fn.rb', line 357

def all_success?
  Fn.all?.(Monad.maybe_value_ok?)
end

.any?Boolean

Returns:

  • (Boolean)


75
76
77
# File 'lib/funcify/fn.rb', line 75

def any?
  ->(f, enum) { enum.any? { |e| f.(e) } }.curry
end

.applyObject

Apply that takes a function and an enum and applies the fn to the entire enum Works with methods like #join, #split



186
187
188
# File 'lib/funcify/fn.rb', line 186

def apply
  ->(f, enum) { f.(enum) }.curry
end

.atObject

right at; takes the key/index and applies the enum



230
231
232
# File 'lib/funcify/fn.rb', line 230

def at
  ->(x, i) { i[x] unless i.nil? }.curry
end

.break_pointObject



287
288
289
# File 'lib/funcify/fn.rb', line 287

def break_point
  -> args { binding.pry }
end

.change_set_fnObject

f: add fn g: remove fn prev state this state



311
312
313
314
315
316
# File 'lib/funcify/fn.rb', line 311

def change_set_fn
  -> f, g, prev, this {
    f.(Set.new(this) - Set.new(prev))
    g.(Set.new(prev) - Set.new(this))
  }.curry
end

.coherseObject



243
244
245
# File 'lib/funcify/fn.rb', line 243

def coherse
  -> f, xs { map.(-> x { x.send(f) } ).(xs) }.curry
end

.composeObject

the famous compose Applies from right to left, taking the result of 1 fn and injecting into the next No Monads tho! compose.(-> n { n + 1}, -> n { n * 2 }).(10)



164
165
166
# File 'lib/funcify/fn.rb', line 164

def compose
  ->(*fns) { fns.reduce { |f, g| lambda { |x| f.(g.(x)) } } }
end

.ctx_valueObject



279
280
281
# File 'lib/funcify/fn.rb', line 279

def ctx_value
  ->(v) { v.context }
end

.delimiter_detokeniserObject



326
327
328
# File 'lib/funcify/fn.rb', line 326

def delimiter_detokeniser
  -> delimiter, f, enum { map.(f, enum).join(delimiter) }.curry
end

.delimiter_tokeniserObject

Takes a collection and generates a string delimited by the delimiter (such as “|”) Returns a curryed fn (ready for the collection) that takes 2 params:

Parameters:

  • f,

    a function that extracts the properties from a map; e.g. F.map.(F.identity)

  • enum,

    the map



322
323
324
# File 'lib/funcify/fn.rb', line 322

def delimiter_tokeniser
  -> delimiter, f, enum { f.(enum).join(delimiter) }.curry
end

.detokeniser(delimiter) ⇒ Object



330
331
332
# File 'lib/funcify/fn.rb', line 330

def detokeniser(delimiter)
  ->(str) { str.split(delimiter) }.curry
end

.eitherObject

The little Either Cond returns either the result of f_ok || f_fail by applying the value to test t. > either.(maybe_value_ok, identity, maybe_failure).(Success(1)) => Success(1)



143
144
145
# File 'lib/funcify/fn.rb', line 143

def either
  ->(test, f_ok, f_fail, value) { test.(value) ? f_ok.(value) : f_fail.(value) }.curry
end

.empty?Boolean

Returns:

  • (Boolean)


291
292
293
# File 'lib/funcify/fn.rb', line 291

def empty?
  -> xs { xs.empty? }
end

.equalityObject

+ field; the property to extract from the record. Either a String/Symb or a Proc which takes the record + test_value; the value which has == applied to determine equality + i; the record under test e.g. equality.(:a).(“equal”).(“equal”) e.g. equality.(test_fn).(“equal”).(“equal”)) ; where test_fn is -> x { x }



195
196
197
198
199
200
201
202
203
# File 'lib/funcify/fn.rb', line 195

def equality
  ->( field, test_value, i ) {
    if field.kind_of?(Proc)
      field.(i) == test_value
    else
      i[field] == test_value
    end
  }.curry
end

.failureObject



251
252
253
# File 'lib/funcify/fn.rb', line 251

def failure
  -> v { Failure(v) }
end

.findObject

finds the first element in a collecton where f.(e) is true



47
48
49
# File 'lib/funcify/fn.rb', line 47

def find
  ->(f, enum) { enum.find { |e| f.(e) } }.curry
end

.firstObject



97
98
99
# File 'lib/funcify/fn.rb', line 97

def first
  -> xs { xs.first }
end

.flattenObject



112
113
114
# File 'lib/funcify/fn.rb', line 112

def flatten
  -> xs { xs.flatten }
end

.fmapObject



16
17
18
# File 'lib/funcify/fn.rb', line 16

def fmap
  ->(f, enum) { enum.flat_map {|e| f.(e) } }.curry
end

.fmap_composeObject

Monadic Compose, using flat_map The result of a fn must return an Either. fmap_compose.([->(v) { M.Success(v + 1) }, ->(v) { M.Success(v + 10) }]).(M.Success(0))



171
172
173
174
175
# File 'lib/funcify/fn.rb', line 171

def fmap_compose
  ->(fns, value) {
    fns.inject(value) {|result, fn| result.success? ? result.fmap(fn).value_or : result}
  }.curry
end

.fmapr_composeObject

reverse version of fmap_compose



178
179
180
181
182
# File 'lib/funcify/fn.rb', line 178

def fmapr_compose
  ->(*fns) {
    -> x { fns.reverse.inject(x) {|x, fn| x.success? ? x.fmap(fn).value_or : x} }
  }
end

.group_byObject



28
29
30
# File 'lib/funcify/fn.rb', line 28

def group_by
  -> f, xs { xs.group_by { |x| f.(x) } }.curry
end

.hash_to_tokensObject



361
362
363
# File 'lib/funcify/fn.rb', line 361

def hash_to_tokens
  compose.(join.(","), Map.map.(-> k, v { "#{k}:#{v}"}))
end

.identityObject



132
133
134
# File 'lib/funcify/fn.rb', line 132

def identity
  ->(i) { i }
end

.includeObject

x can either be an array or a string



206
207
208
# File 'lib/funcify/fn.rb', line 206

def include
  -> x, v { x.include?(v) }.curry
end

.injectObject



24
25
26
# File 'lib/funcify/fn.rb', line 24

def inject
  -> acc, f, xs { xs.inject(acc) {|acc, x| f.(acc).(x) } }.curry
end

.joinObject



59
60
61
# File 'lib/funcify/fn.rb', line 59

def join
  -> sep, i { i.join(sep) }.curry
end

.lastObject



93
94
95
# File 'lib/funcify/fn.rb', line 93

def last
  -> xs { xs.last }
end

.latObject

left at; takes the enum and applies the key/index to it.



235
236
237
# File 'lib/funcify/fn.rb', line 235

def lat
  ->(i, x) { i[x] }.curry
end

.liftObject

lifts the value, otherwise returns nil



117
118
119
# File 'lib/funcify/fn.rb', line 117

def lift
  ->(f, with, i) { f.(i) ? with.(i) : nil }.curry
end

.lift_monadObject



128
129
130
# File 'lib/funcify/fn.rb', line 128

def lift_monad
  -> value { maybe_value_ok?.(value) ? maybe_value.(value) : maybe_failure.(value) }
end

.lift_valueObject

> lift_value.(maybe_value_ok, maybe_value),



124
125
126
# File 'lib/funcify/fn.rb', line 124

def lift_value
  ->(value_type, f) { Fn.lift.(value_type, f) }.curry
end

.linclusionObject



216
217
218
# File 'lib/funcify/fn.rb', line 216

def linclusion
  ->( field, value, i ) { i[field].include?(value) }.curry
end

.mapObject

Common curried map higher order fn > map.(-> i { i.to_s } ).([1,2,3])



12
13
14
# File 'lib/funcify/fn.rb', line 12

def map
  ->(f, enum) { enum.map {|e| f.(e) } }.curry
end

.matchObject

takes a regex and applies it to a value



221
222
223
# File 'lib/funcify/fn.rb', line 221

def match
  ->(r, i) { i.match(r) }.curry
end

.maxObject



67
68
69
# File 'lib/funcify/fn.rb', line 67

def max
  ->(f, enum) { f.(enum).max }.curry
end

.max_intObject



247
248
249
# File 'lib/funcify/fn.rb', line 247

def max_int
  -> limit, i { i > limit ? limit : i }.curry
end

.maybe_failureObject



271
272
273
# File 'lib/funcify/fn.rb', line 271

def maybe_failure
  ->(v) { v.failure }
end

.maybe_pipelineObject

Provides a Maybe pipeline wrapped in a Lambda. This allows the pipeline functions to be applied first, and returns a function which allows the injection of the params to be applied into the beginning of the pipeline. e.g. pipeline = maybe_pipeline.([-> x { Success(x + 1) } ] ) pipeline.value_or.(Success(1)) => Success(2)



341
342
343
344
345
346
347
348
349
# File 'lib/funcify/fn.rb', line 341

def maybe_pipeline
  ->(pipeline) {
    Success(lambda do |value|
      pipeline.inject(value) do |result, fn|
        result.success? ? result.fmap(fn).value_or : result
      end
    end)
  }
end

.maybe_valueObject



267
268
269
# File 'lib/funcify/fn.rb', line 267

def maybe_value
  ->(v) { v.value_or }
end

.maybe_value_fail?Boolean

Returns:

  • (Boolean)


263
264
265
# File 'lib/funcify/fn.rb', line 263

def maybe_value_fail?
  -> v { v.respond_to?(:failure?) && v.failure? }
end

.maybe_value_ok?Boolean

Returns:

  • (Boolean)


259
260
261
# File 'lib/funcify/fn.rb', line 259

def maybe_value_ok?
  ->(v) { v.respond_to?(:success?) && v.success? }
end

.mergeObject



32
33
34
# File 'lib/funcify/fn.rb', line 32

def merge
  -> to, with { to.merge(with) }.curry
end

.methodObject



136
137
138
# File 'lib/funcify/fn.rb', line 136

def method
  -> m, obj { obj.send(m) }.curry
end

.method_callerObject



283
284
285
# File 'lib/funcify/fn.rb', line 283

def method_caller
  -> obj, method, v { obj.send(method, v) }.curry
end

.none?Boolean

Returns:

  • (Boolean)


79
80
81
# File 'lib/funcify/fn.rb', line 79

def none?
  ->(f, enum) { enum.none? { |e| f.(e) } }.curry
end

.nothingObject



299
300
301
# File 'lib/funcify/fn.rb', line 299

def nothing
  -> x { nil }
end

.partitionObject

> partition.(-> x { x == 1 }).([1,1,2,3,4])



89
90
91
# File 'lib/funcify/fn.rb', line 89

def partition
  -> f, enum { enum.partition { |e| f.(e) } }.curry
end

.present?Boolean

Returns:

  • (Boolean)


295
296
297
# File 'lib/funcify/fn.rb', line 295

def present?
  -> x { x.present? }
end

.removeObject

Curryed fn that removes elements from a collection where f.(e) is true



37
38
39
# File 'lib/funcify/fn.rb', line 37

def remove
  ->(f, enum) { enum.delete_if {|e| f.(e) } }.curry
end

.remove_nilObject



303
304
305
# File 'lib/funcify/fn.rb', line 303

def remove_nil
  Fn.remove.(->(i) { i.nil? } )
end

.replaceObject



55
56
57
# File 'lib/funcify/fn.rb', line 55

def replace
  ->(r, with, s) { s.gsub(r,with)  }.curry
end

.restObject



101
102
103
104
105
106
# File 'lib/funcify/fn.rb', line 101

def rest
  -> xs {
    _a, *b = xs
    b
  }
end

.rincludeObject

Right Include, where the value is applied partially waiting for the test prop



211
212
213
# File 'lib/funcify/fn.rb', line 211

def rinclude
  -> v, x { x.include?(v) }.curry
end

.selectObject



51
52
53
# File 'lib/funcify/fn.rb', line 51

def select
  ->(f, enum) { enum.select { |e| f.(e) } }.curry
end

.sequenceObject



20
21
22
# File 'lib/funcify/fn.rb', line 20

def sequence
  ->(fs, i) { fs.inject([]) { |r, f| r << f.(i) } }.curry
end

.splitObject



63
64
65
# File 'lib/funcify/fn.rb', line 63

def split
  -> sep, i { i.split(sep) }.curry
end

.status_value_ok?Boolean

Returns:

  • (Boolean)


275
276
277
# File 'lib/funcify/fn.rb', line 275

def status_value_ok?
  ->(v) { v.status == :ok }
end

.successObject



255
256
257
# File 'lib/funcify/fn.rb', line 255

def success
  -> v { Success(v) }
end

.takeObject



225
226
227
# File 'lib/funcify/fn.rb', line 225

def take
  ->(f, i) { f.(i) unless i.nil? }.curry
end

.testsObject

success_fn: a test fn to apply to the enum resulting from applying the tests; e.g. Fn.all? (and) or Fn.any? (or) test_fns : [test_fn]; each test is called with (value) value : the test context (can be anything understood by the tests) > tests.(all?, [-> x { x == 1}]).(1) => true



151
152
153
154
155
156
157
158
# File 'lib/funcify/fn.rb', line 151

def tests
  -> success_fn, test_fns, value {
    Fn.compose.(
      success_fn.(Fn.identity),                   # provide a results extractor fn to the success_fn
      Fn.map.(-> test_fn { test_fn.(value) } ),    # call each test fn with the context
    ).(test_fns)
  }.curry
end

.uniqObject



84
85
86
# File 'lib/funcify/fn.rb', line 84

def uniq
  -> f, enum { enum.uniq { |e| f.(e) } }.curry
end

.when_nil?Boolean

Returns:

  • (Boolean)


108
109
110
# File 'lib/funcify/fn.rb', line 108

def when_nil?
  ->(i) { i.nil? }
end

.wrapperObject

takes a function which is ready to be executed and wraps it in a function which will finally invoke it, by calling with empty arguments



353
354
355
# File 'lib/funcify/fn.rb', line 353

def wrapper
  -> fn { -> { fn } }
end