Skip to content

Instantly share code, notes, and snippets.

@rev22
Created November 10, 2014 01:37
Show Gist options
  • Save rev22/5e2058959cf96582d715 to your computer and use it in GitHub Desktop.
Save rev22/5e2058959cf96582d715 to your computer and use it in GitHub Desktop.
transducer.coffee
Transducer =
employ: (x)-> x.call @
# Privitive transducers
map: (f)-> (conj)-> (a,b)-> conj(f(a), b)
mapcat: (f)-> (conj)-> (a,b)-> f(conj)(a, b)
filter: (f)-> (conj)-> (a,b)-> if f(a) then conj(a,b) else b
# Operator for binary composition of transducers
comp2: (a,b)-> (conj)-> a(b(conj))
# N-ary composition of transducers
comp: (args...)-> (conj)->
c = args.length
conj = args[--c](conj) while c
conj
Array::reducer = (a = @)-> (conj, i)-> i = conj(x, i) for x in a; i
Array::reduce = (conj, i)-> @reducer()(conj,i)
Array::into = (reduce)-> reduce((a,b)=> @push a); @
Array::transduce = (transducer)-> new @constructor().into Transducer.comp(@reducer(), transducer)
x = [ 1, 2, 3, 4, 5 ]
x = x.transduce Transducer.employ ->
@comp(
# 1 2 3 4 5
@filter((x)-> 0 is x % 2 ),
# 2 4
@map((x)-> x * 3 ),
# 6 12
@map((x)-> x * 2 ),
# 12 24
(conj)-> (a,b)-> [ a, -a ].reduce(conj),
# 12 -12 24 -24
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment