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/