例えば次のような関数を定義したとして、渡されたコレクションと同じ型を返す良い方法はないでしょうか? ただし、評価値の順序がおかしくならないようにお願いします。

(defn rotate [n coll]
  (let [at (if (neg? n) (Math/abs n) (- (count coll) n))
       [left right] (split-at at coll)]
    (concat right left)))

こんなやりかたを考えてみましたが、ごちゃごちゃして気持ち悪いですよね。 何かシンプルな方法はないでしょうか?

(defmulti vomit (fn [coll]
                  (if (list? coll) :list (if (vector? coll) :vector))) :default nil)
(defmethod vomit :list [coll] (partial apply list))
(defmethod vomit :vector [coll] (partial into (empty coll)))
(defmethod vomit nil [coll] identity)

(defn rotate [n coll]
  (let [at (if (neg? n) (Math/abs n) (- (count coll) n))
        [left right] (split-at at coll)]
    ((vomit coll) (concat right left))))