       first: -> @a
       last:  -> @d
 
-      rest: -> new T.Digit3 @b, @c, @d
-      init: -> new T.Digit3 @a, @b, @c
+      rest: -> new Digit3 @b, @c, @d
+      init: -> new Digit3 @a, @b, @c
 
       measure: -> norm @a, @b, @c, @d
 
 
     # An empty finger tree.
-    @Empty = {
+    Empty = {
       isEmpty: -> true
 
       reduceLeft:  (z, op) -> z
       reduceRight: (op, z) -> z
 
-      after:  (a) -> new T.Single a
-      before: (a) -> new T.Single a
+      after:  (a) -> new Single a
+      before: (a) -> new Single a
 
       first: ->
       last:  ->

        op1(@l, op2(@m(), op1(@r, z)))

      after: (x) ->
        if @l.constructor == T.Digit4
          { a, b, c, d } = @l
          new T.Deep(new T.Digit2(x, a),
                     (=> @m().after(new T.Node3(b, c, d))),
                     @r)
        else
          new T.Deep @l.after(x), @m, @r

      before: (x) ->
        if @r.constructor == T.Digit4
          { a, b, c, d } = @r
          new T.Deep(@l,
                     (=> @m().before(new T.Node3(a, b, c))),
                     new T.Digit2(d, x))
        else
          new T.Deep @l, @m, @r.before(x)

      first: -> @l.first()
      last:  -> @r.last()

      rest: ->
        if  @l.rest() == T.Empty
          if @m() == T.Empty
            asTree @r
          else
            new T.Deep @m().first().asDigit(), (=> @m().rest()), @r
        else
          new T.Deep @l.rest(), @m, @r

      init: ->
        if  @r.init() == T.Empty
          if @m() == T.Empty
            asTree @l
          else
            new T.Deep @l, (=> @m().init()), @m().last().asDigit()
        else
          new T.Deep @l, @m, @r.init()

      nodes = (n, s) ->
        if n == 0
          null
        else if n == 2 or n % 3 == 1
          Sequence.conj new T.Node2(s.take(3).into([])...),
            -> nodes n-2, s.drop 2
        else if n >= 3
          Sequence.conj new T.Node3(s.take(3).into([])...),
            -> nodes n-3, s.drop 3
        else
          raise new Error "this should not happen"

      app3 = (tLeft, list, tRight) ->
        if tLeft == T.Empty
          Sequence.reduce Sequence.reverse(list), tRight, (t, x) -> t.after x
        else if tRight == T.Empty
          Sequence.reduce list, tLeft, (t, x) -> t.before x
        else if tLeft.constructor == T.Single
          app3(T.Empty, list, tRight).after tLeft.a
        else if tRight.constructor == T.Single
          app3(tLeft, list, T.Empty).before tRight.a
        else
          tmp = Sequence.flatten [asSeq(tLeft.r), list,  asSeq(tRight.l)]
          s = nodes tmp.size(), tmp
          new T.Deep tLeft.l, (-> app3 tLeft.m(), s, tRight.m()), tRight.r

      concat: (t) -> app3 this, null, t


      reduceLeft:  (z, op) -> op z, @a
      reduceRight: (op, z) -> op @a, z

      after:  (x) -> new Deep new Digit1(x), (-> Empty), new Digit1(@a)
      before: (x) -> new Deep new Digit1(@a), (-> Empty), new Digit1(x)

      first: -> @a
      last:  -> @a

      rest: -> Empty
      init: -> Empty

      concat: (t) -> t.after @a

