{
: empty
: new
: is_empty
: push
: pop
: pop_all
: append
: concat
}

Where

Define (concat queues)
    (LIST.reduce queues empty append)

Where

Define (pop_all queue)
    Unfold queue
        Match (pop queue)
        | 'nothing 'nil
        | 'just.{item queue} [item & (Fold queue)]
        ;

Define (push_all queue items)
    (LIST.reduce items queue push)

Define (append a b)
    Iterate {a b} From {a b}
        Match (pop b)
        | 'nothing a
        | 'just.{item b} (Continue (push a item) b)
        ;

Where

Define (push queue item)
    {
    : incoming [item & queue.incoming]
    : outgoing queue.outgoing
    }

Define (pop queue)
    Unfold queue
        Match queue.outgoing
        | 'cons.{item outgoing}
            Let queue
                {
                : incoming queue.incoming
                : outgoing
                }
            In
            'just.{item queue}
        | 'nil
            Match queue.incoming
            | 'nil 'nothing
            | _ (Fold (new (LIST.reverse queue.incoming)))
            ;
        ;

Where

Define (new init)
    {
    : incoming 'nil
    : outgoing init
    }

Let empty
    {
    : incoming 'nil
    : outgoing 'nil
    }

Define (is_empty queue)
    Match queue.incoming
    | 'nil Match queue.outgoing | 'nil True | 'cons._ False ;
    | 'cons._ False
    ;

Where

Let LIST Package "list"