【问题标题】:What is the correct type annotation for this function?此函数的正确类型注释是什么?
【发布时间】:2015-12-17 04:22:26
【问题描述】:

我有以下实用函数,应该是不言自明的:

(ns my.utility-belt
  "Use this everywhere."
  (:use clojure.core.typed))

(ann  zipfn (All [c a b ...] [[a b ... b -> c] (Seqable a) * -> (Seqable c)]))
(defn zipfn
  "Applies f to the interleaved elements of colls. If 2 colls are given, then f
  will recieve 2 arguments, one from each coll. If 3 colls are given, then f
  will receive 3 arguments, and so on. Returns a flat sequence of the results of
  applying f to its args."
  [f & colls]
  (map (partial apply f) (partition (count colls) (apply interleave colls))))

(comment
  (let [c1 [1 2 3 4 5]
        c2 [5 4 3 2 1]]
    (assert (= (zipfn * c1 c2)
               '(5 8 9 8 5)))))

我提供的注释并不完全正确,但我不知道为什么。打电话给(check-ns) 只会给我“Type Error (my/utility_belt.clj:12:51) Bad arguments to polymorphic function in apply in (apply interleave colls)

在这种情况下,正确的类型注释是什么?

【问题讨论】:

  • 只是出于好奇,zipfn 给你什么直接使用map 没有?我似乎找不到任何给他们不相等输出的输入。
  • @Magos zipfn 将任意数量的集合组合成一个集合。这就像zipmapmap 的组合。
  • 是的,但是您随后将其输入map already accepts any number of colls。是不是和map在最小的coll被清空时停止消费有关?
  • 嗯,我没有意识到 map 已经接受了任意数量的 colls 并且 交错了它们,所以它已经做了我想要的。我已经做了 clojure 2 年了,并没有意识到这一点!我在我最初需要zipfn 的代码上测试了map,它的工作原理相同:)

标签: clojure clojure-core.typed


【解决方案1】:

问题是 core.typed 无法推断这是zipfn 的实际类型。解决这个问题的最快方法是告诉 core.typed 忽略 zipfn:no-check 的定义。

(ann ^:no-check zipfn (All [c a b ...] [[a b ... b -> c] (Seqable a) * -> (Seqable c)]))

【讨论】:

  • 认真的吗?那是个奇怪的人……无论如何,谢谢。我想我应该阅读你的论文才能真正理解 core.typed 是如何工作的:)
  • 不幸的是,这个定义很难按原样检查。 apply 是特殊情况,因此如果以高阶方式使用,它将失去其在类型系统中的大部分表现力。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-04-16
  • 2021-05-23
  • 2020-05-26
  • 1970-01-01
  • 1970-01-01
  • 2011-01-22
  • 1970-01-01
相关资源
最近更新 更多