非地图集合谓词?

时间:2017-03-12 04:33:41

标签: clojure

是否有Clojure谓词意味着“收集,而不是地图”?

这样的谓词是有价值的,因为除了地图之外,还可以对所有集合执行许多操作。例如,(apply + ...)(reduce + ...)可以与向量,列表,延迟序列和集合一起使用,但不能与地图一起使用,因为此类上下文中的地图元素最终为clojure.lang.MapEntry s 。它的集合和映射会导致我知道的那些谓词出现问题:

  • sequential?适用于矢量,列表和延迟序列,但对于地图和集合都是错误的。 (seq?类似,但对于向量来说是假的。)
  • coll?seqable?对于集合和地图以及我能想到的其他类型的集合都是正确的。

当然我可以定义这样一个谓词,例如像这样:

(defn coll-but-not-map?
  [xs]
  (and (coll? xs) 
       (not (map? xs))))

或者像这样:

(defn sequential-or-set?
  [xs]
  (or (sequential? xs)
      (set? xs)))

我想知道是否有内置的clojure.core(或贡献的库)谓词可以做同样的事情。

此问题与this onethis one有关,但未得到答案。 (如果我的问题与我未找到的问题重复,我很高兴将其标记为此类。)

2 个答案:

答案 0 :(得分:3)

  

例如(apply + ...)或(reduce + ...)可以与矢量,列表,延迟序列和集合一起使用,但不能与地图一起使用

我认为这与收藏品无关。在您的情况下,您遇到的问题与常规applyreduce应用程序不同,但具有特定的+功能。即使我们在这里使用了一个向量,(apply + [:a :b :c])也无法工作。

我的观点是,您正在尝试解决特定于域的问题,这就是Clojure本身没有通用解决方案的原因。所以使用你能想到的任何正确的谓词。

答案 1 :(得分:2)

我找不到任何符合此描述的内容。我认为你自己的谓词函数清晰,简单,并且如果你发现它有用,很容易包含在你的代码中。

也许您正在编写必须非常通用的代码,但通常情况是函数既接受又返回一致类型的数据。有些情况并非如此,但通常的情况是,如果一个函数可以成为所有交易的杰克,它就会做得太多。

使用您的示例 - 添加数字向量,数字列表或一组数字是有意义的。但是数字地图?它没有意义,除非它可能是地图中包含的值,并且在这种情况下,单个代码片段需要处理添加顺序数据和关联数据是不合理的。该函数应该按照预期的方式交付,并且应该返回一致的内容。这让我想起斯图尔特·塞拉的blog post讨论这方面的一致性。没有更多信息,我只是猜测你的用例,但这是需要考虑的事情。