gpt4 book ai didi

clojure - 使用在另一个方法中定义的方法

转载 作者:行者123 更新时间:2023-12-02 06:22:08 25 4
gpt4 key购买 nike

我正在研究 this koan 的解决方案,其中指出:

Write a function which replicates each element of a sequence a variable number of times.

为此,我想:

  1. 制作一个方法,该方法采用序列和重复每个元素的次数。
  2. 在此方法中定义一个局部方法,将一个值 v 复制 n 次到一个序列中。

考虑到这一点,我编写了以下方法:

(fn dupSeqX [aseq x]
(fn dupx [v x]
(if (= x 1) (list v) (concat v (dupx v (- x 1))))
)
(reverse (reduce #(concat %1 (dupx %2 x)) '() aseq)))

运行此代码时,出现以下错误:

java.security.PrivilegedActionException: java.lang.Exception: Unable to resolve symbol: dupx in this context (NO_SOURCE_FILE:0)

我如何着手创建一个允许我完成这个 koan 的本地方法?

有没有我不知道的“clojure 式”方法?

最佳答案

首先,我们不谈方法:我们谈函数。 clojure 中有些东西可以调用方法,但它不同于函数。如果您停止使用面向对象的行话,您也会失去面向对象的思维方式。

您尝试做的事情是可能的。您基本上想在 dupseqx 函数中创建一个名为 dupx 的新函数。您现在正在做的是创建一个函数,然后将其丢弃(您不对返回值执行任何操作,只返回函数中的最后一个形式)。由于函数就像任何其他值一样,您可以像处理任何其他值一样使用相同的机制:创建一个本地“变量”。这是什么机制?它是本地绑定(bind),它是这样工作的(fn 中的名称只是为了让您可以从自身调用它;它不需要与 let 绑定(bind)的名称相同):

(let [dupx (fn dupx [v x] 
(if (= x 1)
(list v)
(cons v (dupx v (dec x)))))]
(dupx 5 3))

请注意,我更正了一些其他内容。

这个的较短形式(修复双名丑陋):

(letfn [(dupx [v x] (if (= x 1)
(list v)
(cons v (dupx v (dec x)))))]
(dupx 5 3))

在“(let [...]”和匹配的“)”之间的所有内容中,我们现在有一个 dupx 函数。

现在您的其余代码可以正常工作了:

(fn dupSeqX [aseq x]
(letfn [(dupx [v x] (if (= x 1) (list v) (cons v (dupx v (dec x)))))]
(reverse (reduce #(concat %1 (dupx %2 x)) '() aseq))))

可以使这段代码更加地道:

  • 编码指南:名称参数 coll 而不是 aseq
  • 编码指南:DoNotUseCamalCase do-it-like-this
  • 在不需要时递归对性能和大数字不利。
  • 您正在重新发明轮子。这对学习编码来说是件好事,但如果您想了解语言和标准库,那就不好了。

我是如何开始写这篇文章的?

首先是基本的 fn。 coll 是期望序列的命名函数的标准。

(fn [coll times]  )

如果你读到这个“序列的每个元素”,你的大脑必须去 MAP。

(fn [coll times] 
(map (fn ....) coll))

“replicates each ...”基本上是对您必须放入 map 函数中的内容的描述。我们可以使用 repeat(你的 dubx 函数,但有一些额外的好处,比如它是惰性的)。

(fn [coll times] 
(map (fn [val] (repeat times val)) coll))

还剩下一个问题(来自公案)。它想要一个 seq 返回,而不是每个元素的序列中的一个序列。这意味着我们必须将结果连接在一起。

 (fn [coll times] 
(apply concat (map (fn [val] (repeat times val)) coll)))

你会经常看到 (apply concat (map ....)) 模式。标准库中有一个更好的函数,称为 mapcat,我将把内部函数变成短语法。

 (fn [coll times] 
(mapcat #(repeat times %) coll))

希望对您有所帮助!

关于clojure - 使用在另一个方法中定义的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7434586/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com