【问题标题】:Trouble with comp function in ClojureClojure中comp函数的问题
【发布时间】:2022-01-21 07:12:35
【问题描述】:

我有 3 个以前的文件,每个文件都有一个函数,我试图在 ex4.clj 中使用 comp 来组合所有 3 个文件,但目前收到关于传递的 args 数量错误的错误。我尝试过使用 map、reduce 和 filter,但它们都失败了,我不确定如何判断需要哪一个,因为所有函数都使用不同的函数。

ex1.clj

(defn round [input] (Math/round (double input)))

(def testList [4.7 3.3 -17 17 -5.6 -3.3 0])

(def roundedList (map round testList))

ex2.clj

(defn isDivisibleBy [factor]
    (fn [number]
        (def result (/ number factor))
        (def roundedResult (Math/round (double result)))

        (and (= result roundedResult))
    )
)

(def divisibleBy2 (isDivisibleBy 2))

(def testList [2 3 4 17 3000 -3 -6 0])

(def divisibleSuccess (filter divisibleBy2 testList))

ex3.clj

(defn findMax [accum value]
    (if (> accum value) accum value)
)

(def testList [2 3 4 17 3000 -3 0 -3001])
(def maxValue (reduce findMax testList))

ex4.clj(问题文件)

(load-file "ex1.clj")
(load-file "ex2.clj")
(load-file "ex3.clj")

(def testList [4.7 3.3 -17 17 -5.6 -3.3 0])
(def allThree (comp findMax divisibleBy2 round))
(def output ((map/reduce/filter) allThree testList))

(println "Original list: " testList)
(println "Highest rounded number divisible by 2: " output)

谢谢!

【问题讨论】:

  • 这是不合法的map|reduce|filter|。此外,如果您将所有内容放在 1 个文件中开始,会更容易。每个文件都是一个单独的命名空间, & 需要修改语法。请参阅此文档列表,尤其是“Getting Clojure”和“Brave Clojure”书籍。 github.com/io-tupelo/clj-template#documentation
  • 我只是把它放在那里象征我尝试了所有三个。为混乱道歉。我在测试时一次只放一个。即使合并到一个文件中,我也会遇到同样的错误。
  • 你希望这个组合函数能做什么?不使用comp你能写出等价的函数吗?
  • @amalloy 该函数应该取一个列表,将它们四舍五入,根据 2 的可分性进行过滤,然后返回最大值。代码似乎卡住的部分是 findMax 需要 2 个参数,但 comp 函数只传递一个。我试图以咖喱形式重写它,但也遇到了问题。我们必须使用 comp 函数进行赋值。现在的错误是:传递给用户/findMax 的 args (1) 数量错误
  • @amalloy 我可以使用 3 个不同的命令手动完成此操作,这些命令只需从最后一个获取输出并将其放入下一个,这就是我认为 comp 本质上所做的,但它似乎没有工作一样。 (def roundedList (map round testList)) (def divisibleSuccess (filter divisibleBy2 roundedList)) (def output (reduce findMax divisibleSuccess)) 我们刚刚接触了 Clojure,教授提供了使用所有其他函数的示例和指南,但是comp 功能没有太多内容,所有在线信息似乎要么很复杂,要么根本不存在。

标签: clojure


【解决方案1】:

你的函数用于不同的工作:一个是谓词, 你想filter。一个是转型,你要map 超过。最后一个是聚合,你想用作最后一步 (通过reduce)。

所以你必须组合你想要做的转换:

((comp
    (partial reduce findMax)
    (partial filter divisibleBy2)
    (partial map round))
  testList)

如果你想经常这样做,你也应该看看 transducers,允许 这样做没有中间序列的成本。

随机风格评论:

  • Clojure 使用 kebab-case 而不是 camelCase
  • 永远不要在命名空间之外def;请改用let
  • 在谓词(例如 divisible-by-2?)上带有尾随 ? 是很常见的

【讨论】:

  • 感谢您提供的所有重要提示和有用的回复!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-02-22
  • 1970-01-01
  • 1970-01-01
  • 2014-05-13
  • 1970-01-01
  • 1970-01-01
  • 2011-08-04
相关资源
最近更新 更多