dubst_insert_du :: Item -> STRef t (DUTree t) -> ST t ()
dubst_insert_du x tp =
    do
    t <- readSTRef tp
    case t of
        DUEmpty -> -- tp := Node Empty x Empty
            do
            e1 <- newSTRef DUEmpty
            e2 <- newSTRef DUEmpty
            writeSTRef tp (DUNode e1 x e2)
        (DUNode lp n rp) ->
            if x <= n then
                dubst_insert_du x lp
            else
                dubst_insert_du x rp

-- size of tree
-- (doesn't update tree, though this isn't obvious from the type signature)
dubst_insert_du :: Item -> STRef t (DUTree t) -> ST t ()
dubst_insert_du x tp =
    do
    t <- readSTRef tp
    case t of
        DUEmpty -> -- tp := Node Empty x Empty
            do
            e1 <- newSTRef DUEmpty
            e2 <- newSTRef DUEmpty
            writeSTRef tp (DUNode e1 x e2)
        (DUNode lp n rp) ->
            if x <= n then
                dubst_insert_du x lp
            else
                dubst_insert_du x rp

-- size of tree
-- (doesn't update tree, though this isn't obvious from the type signature)
dubst_insert_du x tp =
    do
    t <- readSTRef tp
    case t of
        DUEmpty -> -- tp := Node Empty x Empty
            do
            e1 <- newSTRef DUEmpty
            e2 <- newSTRef DUEmpty
            writeSTRef tp (DUNode e1 x e2)
        (DUNode lp n rp) ->
            if x <= n then
                dubst_insert_du x lp
            else
                dubst_insert_du x rp

-- size of tree
-- (doesn't update tree, though this isn't obvious from the type signature)