 class Single
   constructor: (a) -> @a = a
 
-  reducel: (z, op) -> op z, @a
-  reducer: (op, z) -> op @a, z
+  reduceLeft:  (z, op) -> op z, @a
+  reduceRight: (op, z) -> op @a, z
 
 
 # A deep finger tree.

# --------------------------------------------------------------------


reducel: (op) -> (z, x) -> x.reducel(z, op)
reducer: (op) -> (x, z) -> x.reducer(op, z)


# A node.
class Node2
  constructor: -> [@a, @b] = arguments
  reducel: (z, op) -> op(op(z, @a), @b)
  reducer: (op, z) -> op(@a, op(@b, z))

class Node3
  constructor: -> [@a, @b, @c] = arguments
  reducel: (z, op) -> op(op(op(z, @a), @b), @c)
  reducer: (op, z) -> op(@a, op(@b, op(@c, z)))

make_node = (args...) ->
  type = switch args.length
    when 2 then Digit2
    when 3 then Digit3

# A digit in a finger tree.
class Digit1
  constructor: -> [@a] = arguments
  reduceLeft:  (z, op) -> op(z, @a)
  reduceRight: (op, z) -> op(@a, z)

class Digit2
  constructor: -> [@a, @b] = arguments
  reduceLeft:  (z, op) -> op(op(z, @a), @b)
  reduceRight: (op, z) -> op(@a, op(@b, z))

class Digit3
  constructor: -> [@a, @b, @c] = arguments
  reduceLeft:  (z, op) -> op(op(op(z, @a), @b), @c)
  reduceRight: (op, z) -> op(@a, op(@b, op(@c, z)))

class Digit4
  constructor: -> [@a, @b, @c, @d] = arguments
  reduceLeft:  (z, op) -> op(op(op(op(z, @a), @b), @c), @d)
  reduceRight: (op, z) -> op(@a, op(@b, op(@c, op(@d, z))))

makeDigit = (args...) ->
  type = switch args.length
    when 1 then Digit1
    when 2 then Digit2
