Skip to content

Instantly share code, notes, and snippets.

@ehlyzov
Last active January 1, 2016 18:29
Show Gist options
  • Select an option

  • Save ehlyzov/8183679 to your computer and use it in GitHub Desktop.

Select an option

Save ehlyzov/8183679 to your computer and use it in GitHub Desktop.
ruby trics inspired by FP
#_ собственно, сам укус. Почти незаметный.
(defn my-comp [& f] #((reduce (fn [x j] [(apply j x)]) %& (into () f)) 0))
(= true ((my-comp zero? #(mod % 8) +) 3 5 7 9))
# И все заверте...
# цепочка сообщений методу
mcomp0 = proc {|*ms| ms.inject( ->(_) {_} ) {|f, m| proc {|*as| f[ as.map(&proc(&m)).first ] }}}
4 == mcomp0[:succ, :succ, :succ][1]
# цепочка функций
fcomp0 = proc {|*ms| ms.inject( ->(_) {_} ) {|f, m| proc {|*as| f[ as.map(&m).first ] }}}
fs = [1, 2, 3].map {|n| -> (x) { n + x }}
7 == fcomp0[*fs][1]
# чередовать сообщения и функции?
scomp0 = proc {|*ms| ms.inject( ->(_) {_} ) {|f, m| proc {|*as| f[ as.map(&(m.is_a?(Symbol) ? proc(&m) : m)).first ] }}}
sum = -> (n) { n.inject(&:+) }
mod8 = -> (n) { n % 8}
true == scomp0[:zero?, mod8, sum][[3, 5, 7, 9]]
# TODO сообщения с параметрами - вызовы вида [% 8]
# TODO сообщения с блоком - вызовы вида .inject(&:+) ## [:zero?, [:% 8], [[:inject, :+]]]
# вот это поворот
# SKI наивная реализация
K = ->(x, y) { x }.curry(2)
S = ->(x, y, z) {(x[z])[y[z]]}.curry(3)
I = S[K, K]
K == S[K, S, K]
# Более практично (идея отсюда http://combinators.info/#the-mockingbird)
M = -> (&x) { x.call(x) }
# а это лямбда которая переданной ей функции base
# передает саму себя как параметр
Recur = -> (base) { M[ &proc {|x| -> (a) { base[a, M[&x]] }} ] }
# ПРИМЕР: подсчет количества подмножеств в множестве
count_subsets = Recur[ proc { |a, recurse|
a.kind_of?(Array) ? 1 + a.map(&recurse).inject(&:+) : 0
}]
4 == count_subsets[ [1,[2, 3, 4, [5]], [3]] ]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment