首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Clojure ::arity重载函数相互调用

Clojure ::arity重载函数相互调用
EN

Stack Overflow用户
提问于 2013-02-10 06:59:48
回答 2查看 4.1K关注 0票数 10

Clojure的示例-重载如下所示的函数(取自cookbook):

代码语言:javascript
复制
(defn argcount
  ([] 0)                                ; Zero arguments
  ([x] 1)                               ; One argument
  ([ x &  args] (inc (count args))))    ; List of arguments

..。使用一种形式,似乎不允许较低的函数简单地调用具有一些默认值的较高的函数(这是Java中的一种常见用法)。是否有其他特殊形式用于此目的?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-02-10 10:54:21

通常有一种很好的方法来表达高阶参数,这种方法不需要引用其他使用高阶函数和map / reduce的参数。在本例中,它非常简单:

代码语言:javascript
复制
(defn argcount
  ([] 0)
  ([x] 1)
  ([x & args]
    (reduce + 1 (map (constantly 1) args))))

请注意,表达式的一般形式为:

代码语言:javascript
复制
(reduce reducing-function arity-1-value (map mapping-function rest-of-args))

你不能用这种方式做所有的事情,但是这对于一个多参数函数来说是非常有效的。它还获得了使用map的懒惰的优点,所以你可以做一些疯狂的事情,比如将一千万个参数传递给一个函数,而不用担心:

代码语言:javascript
复制
(apply argcount (take 10000000 (range)))
=> 10000000

在大多数其他语言中尝试一下,你的堆栈就完蛋了:-)

票数 14
EN

Stack Overflow用户

发布于 2013-10-28 00:55:04

mikera的回答很棒;我只需要添加一个额外的方法。当重载函数需要默认值时,可以使用local。

在下面的示例除法中,local需要数字和精度。定义的函数使用默认值重载精度。

代码语言:javascript
复制
(def overloaded-division
 (let [divide-with-precision
  (fn [divisor dividend precision]
    (with-precision precision (/ (bigdec divisor) (bigdec dividend))))]
     (fn
      ;lower-arity calls higher with a default precision.
      ([divisor dividend] (divide-with-precision divisor dividend 10))
      ;if precision is supplied it is used.
      ([divisor dividend precision] (divide-with-precision divisor dividend precision)))
   )
 )

在较低级别调用时,它应用的默认值为:

代码语言:javascript
复制
user=> (overloaded-division 3 7)
0.4285714286M
user=> (overloaded-division 3 7 40)
0.4285714285714285714285714285714285714286M
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14792592

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档