clojure 有一个方便的 (into to-coll from-coll) 函数,将元素从 from-coll 添加到 to-coll ,保留 to-coll 的类型。

如何在普通的 lisp 中实现这一点?
第一次尝试是

(defun into (seq1 seq2)
  (concatenate (type-of seq1) seq1 seq2))

但是这个显然失败了,因为 type-of 在它的结果中包含了向量的长度,不允许添加更多元素(从 sbcl 开始),尽管它仍然适用于列表作为第一个参数
(虽然仍然无法获得空列表)。

问题是:是否可以在不使用通用方法和/或复杂的 type-of 结果处理(例如,去除向量/数组等的长度)的情况下组成这种函数?

我可以将 into 用作 append(与 clojure 相反,其中 into 结果取决于目标集合类型)让我们称之为 concat-into

最佳答案

在 Clojure 中,当你使用 into 时,你对第一个集合是什么类型有一个具体的想法(大部分时间),因为它改变了语义:如果它是一个列表,额外的元素将被 conj ed 到前面,如果它是向量,后面会被 conj ed,如果是映射,则需要提供映射条目指示符(即实际映射条目或二元向量),集合更灵活,但也带有自己的语义。这就是为什么我猜测直接使用 concatenate ,显式提供类型,可能足以满足许多用例。

除此之外,我认为扩展此功能可能很有用(Common Lisp 只有一组封闭的序列类型),但为此,使用泛型函数忽略似乎太方便了。提供可扩展、通用和高性能的解决方案并非易事。

编辑:总而言之:不,您无法通过巧妙地应用一两个“内置函数”来获得这种行为,但是您当然可以使用通用函数编写可扩展的通用解决方案。

关于clojure 的 `into` 在普通 lisp 中,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/59294775/

10-12 07:33