Alf*_*oli 36 clojure currying higher-order-functions
Clojure很棒,我们都知道这一点,但这不是重点.我想知道以类似Haskell的方式创建和管理高阶函数的惯用方法是什么.在Clojure中,我可以执行以下操作:
(defn sum [a b] (+ a b))
Run Code Online (Sandbox Code Playgroud)
但是(sum 1)
不返回函数:它会导致错误.当然,你可以这样做:
(defn sum
([a] (partial + a))
([a b] (+ a b)))
Run Code Online (Sandbox Code Playgroud)
在这种情况下:
user=> (sum 1)
#<core$partial$fn__3678 clojure.core$partial$fn__3678@1acaf0ed>
user=> ((sum 1) 2)
3
Run Code Online (Sandbox Code Playgroud)
但这似乎不是正确的方法.有任何想法吗?
我不是在谈论实现这个sum
功能,我正在谈论更高层次的抽象.是否有任何惯用模式可供遵循?有些宏?是定义宏的最佳方式还是有替代解决方案?
我已经玩过amalloy建议的功能了.我不喜欢明确规定咖喱的论点数量.所以我创建了自定义宏.这是特定高阶函数的旧方法:
(defn-decorated old-sum
[(curry* 3)]
[a b c]
(+ a b c))
Run Code Online (Sandbox Code Playgroud)
这是我的新宏:
(defmacro defn-ho
[fn-name & defn-stuff]
(let [number-of-args (count (first defn-stuff))]
`(defn-decorated ~fn-name [(curry* ~number-of-args)] ~@defn-stuff)))
Run Code Online (Sandbox Code Playgroud)
这是新的隐含方式:
(defn-ho new-sum [a b c] (+ a b c))
Run Code Online (Sandbox Code Playgroud)
如你所见,没有(咖喱)和其他东西的痕迹,只需像以前一样定义你的currified函数.
伙计们,你怎么看?想法?建议?再见!
Alfedo
编辑:我根据有关docstring的合金问题修改了宏.这是更新版本:
(defmacro defhigh
"Like the original defn-decorated, but the number of argument to curry on
is implicit."
[fn-name & defn-stuff]
(let [[fst snd] (take 2 defn-stuff)
num-of-args (if (string? fst) (count snd) (count fst))]
`(defn-decorated ~fn-name [(curry* ~num-of-args)] ~@defn-stuff)))
Run Code Online (Sandbox Code Playgroud)
我不喜欢第二个绑定中的if语句.关于让它变得更加舒适的任何想法?
归档时间: |
|
查看次数: |
11099 次 |
最近记录: |