【问题标题】:Clojure Core.Typed annotation for apply用于应用的 Clojure Core.Typed 注释
【发布时间】:2014-01-21 17:57:54
【问题描述】:

我将再次通过项目 euler 来发展和磨练我的 core.typed 技能。但是,我很难理解类型检查器的输出。在阅读了 core.typed 的一些介绍性材料以及 core.typed wiki 上的一些信息后,我提出了这个问题。

我正在使用以下代码,请注意apply 的注释以及将num 映射到函数euler3 中的输入没有任何效果。仍然会生成错误消息。请忽略明显不好的factors 和prime? 函数。我选择了幼稚的实现来让我专注于类型注释。

(ns euler-clj.euler3
"Project euler problem 3.
 Uses a very naive prime tester, would use a sieve or probabilistic
 prime algorithm for a larger problem set.
 What is the largest prime factor of the number 600851475143?"

(:require [clojure.core.typed :refer
          [ann check-ns Int fn> non-nil-return Seq cf]]
          [euler-clj.euler1 :as e1]))

(non-nil-return clojure.lang.Numbers/quotient :all)
(ann ^:no-check clojure.core/apply [[Number Number * -> Number] (Seq Number) -> Number])

(ann factors [Int -> (Seq Int)])
(defn factors
  [n]
  (filter (fn> [m :- Int] (e1/div-by m n)) (range 1 (inc (quot n 2)))))

; Very bad prime function, should be sieve/probabilistic.
; Also identifies 1 as prime incorrectly.
(ann prime? [Int -> Boolean])
(defn prime? [n] (= [1] (factors n)))

(ann euler3 [Int -> Number])
(defn euler3
  [n]
  (apply max (map num (filter prime? (factors n)))))

(ann -main [-> nil])
(defn -main
  []
  (prn (euler3 600851475143)))

这会产生以下错误:

类型错误 (euler-clj.euler3:26:3) 要应用的错误参数: 目标:(Fn [java.lang.Number java.lang.Number * -> java.lang.Number]) 参数:(clojure.core.typed/Seq java.lang.Number) 在: (clojure.core/apply clojure.core/max (clojure.core/map clojure.core/num (clojure.core/filter euler-clj.euler3/prime? (euler-clj.euler3/因素 n)))) ExceptionInfo 类型检查器:发现 1 个错误 clojure.core/ex-info (core.clj:4327) 开始收集euler-clj.euler3 开始收集euler-clj.euler1 收集完毕 euler-clj.euler1 收集完毕 euler-clj.euler3 在 62.584894 毫秒内收集了 2 个命名空间 开始检查 euler-clj.euler1 在 165.76663 毫秒内检查了 euler-clj.euler1 开始检查 euler-clj.euler3 在 200.997234 毫秒内检查了 euler-clj.euler3 在 430.302357 毫秒内检查了 2 个命名空间(大约 60 行)

我需要提供什么类型的注释才能申请接受最大值,然后接受这个数字序列?

谢谢

【问题讨论】:

    标签: clojure clojure-core.typed


    【解决方案1】:

    首先,您不应该为apply 提供您自己的类型;它在类型检查器中作为特例实现。

    在这种情况下,core.typed 需要说服max 永远不会被零参数调用。

    这是一种方法:

    (ann euler3 [Int -> Number])
    (defn euler3
      [n]
      (let [[f & r] (map num (filter prime? (factors n)))]
        (if f
          (apply max f r)
          (throw (Exception. "No prime factors")))))
    

    【讨论】:

    • 嘿安布罗斯,非常感谢您的回复,一旦您指出答案,答案就很明显了。哈哈。我很确定 apply 有一个内置注释,但是当您尝试注释大多数核心功能时,我没有收到关于重复注释的警告。有些人会发出警告而有些人不会发出警告是有原因的吗?
    • apply 没有可依赖的基本注释,因此用户添加的任何注释都可能是唯一存在的注释。我们可以给apply 一些可能的注释,每一个都有不同的优缺点。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多