This is a series of very basic lambdas:
# We base our examples from this object:
user = { name: "Joe", age: "23", created_at: "2023-03-01" }
id = same = ->a { a }
at = ->key, a { a[key] }.curry
fetch = ->key, a { a.fetch(key) }.curry
get = ->key, a { a.send(key) }.curry
set = ->key, value, a { a.send(:key, a) }.curry
size = get.(:size)
count = get.(:count)
uniq = get.(:uniq)
map = ->fn, a { a.map(&fn) }.curry
maybe = ->fn, a { a.nil? ? a : fn.(a) }.curry
default = ->default, a { a.nil? ? default : a }.curry
# validations
is_a = ->klass, a { a.is_a?(klass) ? a : (raise "Invalid class, expected #{klass} was #{a.class} for #{a}") }.curry
# Conversion
to_sym = get.(:to_sym)
to_s = get.(:to_s)
to_i = ->a { a.to_i }
require 'time'
parse_time = ->a { Time.parse(a) }
to_date = get.(:to_date)
require "json"
to_json = ->a { a.to_json }
from_json = ->a { JSON.parse(a) }
# Pretty
pretty_inspect = ->a { a.pretty_inspect }
pretty_json = ->str { JSON.pretty_generate(JSON.parse(str)) }
require "nokogiri"
pretty_xml = ->(xml_str) do
doc = Nokogiri::XML(xml_str) { |config| config.default_xml.noblanks }
doc.to_xml(indent: 2)
end
pretty_html = ->str { Nokogiri::HTML(str).tap { |a| a.to_html(indent: 2) } }
# Printers
p_ = ->a { p a }
debug = ->label, a { puts "#{label}: #{a.inspect}"; a }.curry
##############
### hash
##############
map_keys = -> fn, a { a.map{|k, v| [fn.(k), v]}.to_h}.curry
keys_to_sym = map_keys.(to_sym)
# Return ssss the given fields, in the same order as the list of params
only = ->(*keys) { ->h { keys.map { |k| [k, h[k]] }.to_h } }
only.(:name, :age).(user)
#=> {:name=>"martin", :age=>12}
except = ->(*keys) { -> h { h.reject { |k, _| keys.include?(k) }} }
except.(:name, :age).(user)
#=> {:name=>"martin", :age=>12}
# Filters the input hash to include only the keys specified in the `defn` hash.
# For each key, applies the corresponding lambda function from `defn` to the
# value from the input hash. Returns a new hash with the transformed values.
def_h = ->defn, input {
defn.each_with_object({}) do |(key, fn), result|
result[key] = fn.(input[key])
end
}.curry
conv = ->(conversion_hash, target_hash) do
target_hash.map do |key, value|
[key, conversion_hash.key?(key) ? conversion_hash[key].(value) : value]
end.to_h
end.curry
# Example
user_def = def_h.(name: same,
created_at: is_a.(String) >> parse_time >> to_date,
country: default.("Canada"))
user_def.(user)
# => {:name=>"Joe", :created_at=>"2023-03-01", :country=>"Canada"}