class Funcify::Fn
Public Class Methods
add an element to an array
# File lib/funcify/fn.rb, line 42 def add -> x, xs { xs << x }.curry end
# File lib/funcify/fn.rb, line 71 def all? ->(f, enum) { enum.all? { |e| f.(e) } }.curry end
# 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
# File lib/funcify/fn.rb, line 357 def all_success? Fn.all?.(Monad.maybe_value_ok?) end
# File lib/funcify/fn.rb, line 75 def any? ->(f, enum) { enum.any? { |e| f.(e) } }.curry end
Apply that takes a function and an enum and applies the fn to the entire enum Works with methods like join, split
# File lib/funcify/fn.rb, line 186 def apply ->(f, enum) { f.(enum) }.curry end
right at; takes the key/index and applies the enum
# File lib/funcify/fn.rb, line 230 def at ->(x, i) { i[x] unless i.nil? }.curry end
# File lib/funcify/fn.rb, line 287 def break_point -> args { binding.pry } end
f: add fn g: remove fn prev state this state
# 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
# File lib/funcify/fn.rb, line 243 def coherse -> f, xs { map.(-> x { x.send(f) } ).(xs) }.curry end
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)
# File lib/funcify/fn.rb, line 164 def compose ->(*fns) { fns.reduce { |f, g| lambda { |x| f.(g.(x)) } } } end
# File lib/funcify/fn.rb, line 279 def ctx_value ->(v) { v.context } end
# File lib/funcify/fn.rb, line 326 def delimiter_detokeniser -> delimiter, f, enum { map.(f, enum).join(delimiter) }.curry end
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: @param f, a function that extracts the properties from a map; e.g. F.map.(F.identity) @param enum, the map
# File lib/funcify/fn.rb, line 322 def delimiter_tokeniser -> delimiter, f, enum { f.(enum).join(delimiter) }.curry end
# File lib/funcify/fn.rb, line 330 def detokeniser(delimiter) ->(str) { str.split(delimiter) }.curry end
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)
# 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
# File lib/funcify/fn.rb, line 291 def empty? -> xs { xs.empty? } end
+ 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”).({a: “equal”}) e.g. equality.(test_fn).(“equal”).({a: “equal”})) ; where test_fn is -> x { x }
# 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
# File lib/funcify/fn.rb, line 251 def failure -> v { Failure(v) } end
finds the first element in a collecton where f.(e) is true
# File lib/funcify/fn.rb, line 47 def find ->(f, enum) { enum.find { |e| f.(e) } }.curry end
# File lib/funcify/fn.rb, line 97 def first -> xs { xs.first } end
# File lib/funcify/fn.rb, line 112 def flatten -> xs { xs.flatten } end
# File lib/funcify/fn.rb, line 16 def fmap ->(f, enum) { enum.flat_map {|e| f.(e) } }.curry end
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))
# 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
reverse version of fmap_compose
# 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
# File lib/funcify/fn.rb, line 28 def group_by -> f, xs { xs.group_by { |x| f.(x) } }.curry end
# File lib/funcify/fn.rb, line 361 def hash_to_tokens compose.(join.(","), Map.map.(-> k, v { "#{k}:#{v}"})) end
# File lib/funcify/fn.rb, line 132 def identity ->(i) { i } end
x can either be an array or a string
# File lib/funcify/fn.rb, line 206 def include -> x, v { x.include?(v) }.curry end
# File lib/funcify/fn.rb, line 24 def inject -> acc, f, xs { xs.inject(acc) {|acc, x| f.(acc).(x) } }.curry end
# File lib/funcify/fn.rb, line 59 def join -> sep, i { i.join(sep) }.curry end
# File lib/funcify/fn.rb, line 93 def last -> xs { xs.last } end
left at; takes the enum and applies the key/index to it.
# File lib/funcify/fn.rb, line 235 def lat ->(i, x) { i[x] }.curry end
lifts the value, otherwise returns nil
# File lib/funcify/fn.rb, line 117 def lift ->(f, with, i) { f.(i) ? with.(i) : nil }.curry end
# File lib/funcify/fn.rb, line 128 def lift_monad -> value { maybe_value_ok?.(value) ? maybe_value.(value) : maybe_failure.(value) } end
Takes a structure (like a Monad
), an OK test fn, and a fn to extract when OK Returns the result of f, otherwise nil > lift_value.(maybe_value_ok, maybe_value
),
# File lib/funcify/fn.rb, line 124 def lift_value ->(value_type, f) { Fn.lift.(value_type, f) }.curry end
# File lib/funcify/fn.rb, line 216 def linclusion ->( field, value, i ) { i[field].include?(value) }.curry end
Common curried map higher order fn > map.(-> i { i.to_s } ).([1,2,3])
# File lib/funcify/fn.rb, line 12 def map ->(f, enum) { enum.map {|e| f.(e) } }.curry end
takes a regex and applies it to a value
# File lib/funcify/fn.rb, line 221 def match ->(r, i) { i.match(r) }.curry end
# File lib/funcify/fn.rb, line 67 def max ->(f, enum) { f.(enum).max }.curry end
# File lib/funcify/fn.rb, line 247 def max_int -> limit, i { i > limit ? limit : i }.curry end
# File lib/funcify/fn.rb, line 271 def maybe_failure ->(v) { v.failure } end
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)
# 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
# File lib/funcify/fn.rb, line 267 def maybe_value ->(v) { v.value_or } end
# File lib/funcify/fn.rb, line 263 def maybe_value_fail? -> v { v.respond_to?(:failure?) && v.failure? } end
# File lib/funcify/fn.rb, line 259 def maybe_value_ok? ->(v) { v.respond_to?(:success?) && v.success? } end
# File lib/funcify/fn.rb, line 32 def merge -> to, with { to.merge(with) }.curry end
# File lib/funcify/fn.rb, line 136 def method -> m, obj { obj.send(m) }.curry end
# File lib/funcify/fn.rb, line 283 def method_caller -> obj, method, v { obj.send(method, v) }.curry end
# File lib/funcify/fn.rb, line 79 def none? ->(f, enum) { enum.none? { |e| f.(e) } }.curry end
# File lib/funcify/fn.rb, line 299 def nothing -> x { nil } end
> partition.(-> x { x == 1 }).([1,1,2,3,4])
# File lib/funcify/fn.rb, line 89 def partition -> f, enum { enum.partition { |e| f.(e) } }.curry end
# File lib/funcify/fn.rb, line 295 def present? -> x { x.present? } end
Curryed fn that removes elements from a collection where f.(e) is true
# File lib/funcify/fn.rb, line 37 def remove ->(f, enum) { enum.delete_if {|e| f.(e) } }.curry end
# File lib/funcify/fn.rb, line 303 def remove_nil Fn.remove.(->(i) { i.nil? } ) end
# File lib/funcify/fn.rb, line 55 def replace ->(r, with, s) { s.gsub(r,with) }.curry end
# File lib/funcify/fn.rb, line 101 def rest -> xs { _a, *b = xs b } end
Right Include, where the value is applied partially waiting for the test prop
# File lib/funcify/fn.rb, line 211 def rinclude -> v, x { x.include?(v) }.curry end
# File lib/funcify/fn.rb, line 51 def select ->(f, enum) { enum.select { |e| f.(e) } }.curry end
# File lib/funcify/fn.rb, line 20 def sequence ->(fs, i) { fs.inject([]) { |r, f| r << f.(i) } }.curry end
# File lib/funcify/fn.rb, line 63 def split -> sep, i { i.split(sep) }.curry end
# File lib/funcify/fn.rb, line 275 def status_value_ok? ->(v) { v.status == :ok } end
# File lib/funcify/fn.rb, line 255 def success -> v { Success(v) } end
# File lib/funcify/fn.rb, line 225 def take ->(f, i) { f.(i) unless i.nil? }.curry end
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
# 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
# File lib/funcify/fn.rb, line 84 def uniq -> f, enum { enum.uniq { |e| f.(e) } }.curry end
# File lib/funcify/fn.rb, line 108 def when_nil? ->(i) { i.nil? } end
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
# File lib/funcify/fn.rb, line 353 def wrapper -> fn { -> { fn } } end