前一段时间学习Haskell,我感觉爱上了无点符号,特别方便的部分功能应用 - 只需提供你知道的args。在Clojure中,我一直有partial
。我认为在阅读器中使用特殊语法会很好。
查看示例代码:
; Notation with points:
(map (+ 10 (* % 2)) [1 2 3])
; With partial:
(map (comp (partial + 10) (partial * 2)) [1 2 3])
; Let #[] syntax means partial application in reader:
(map (comp #[+ 10] #[* 2]) [1 2 3])
这太好了!有这样的事吗?是否有可能定义自定义阅读器宏?
答案 0 :(得分:6)
匿名函数语法#(...)可以与您尝试执行的操作类似地使用:
user=> (map (comp (partial + 10) (partial * 2)) [1 2 3])
(12 14 16)
相当于:
user=> (map (comp #(+ 10 %) #(* 2 %)) [1 2 3])
(12 14 16)
微小的差别是%
,这只是一个函数参数,在这种情况下是第一个和唯一的。
答案 1 :(得分:5)
我非常喜欢你使用#[]文字的部分函数表示法的想法。
不幸的是,Clojure不允许我们直接增强#()表示法,但我们可以为部分应用程序定义一个像#p
这样的宏。
鉴于你有一个功能
(defn partial-wrap
[args]
(concat '(partial) args))
在myapp.core
中定义。
您可以将以下条目添加到类路径顶部的data_readers.clj
中:
{p myapp.core/partial-wrap}
(通常应该使用名称空间限定符号,例如a/p
,因为不合格的符号是为Clojure保留的。但是不合格的符号确实有用,你需要依赖Clojure在未来的版本中不覆盖它们。) / p>
这最终几乎可以满足您的要求:
(map (comp #p[+ 10] #p[* 2]) [1 2 3])
=> (12 14 16)
答案 2 :(得分:2)
我发现了一种在我的问题中有部分情况的方法:(map #(+ 10 (* 2 %)) [1 2 3)
。使用->>
宏:(map #(->> % (* 2) (+ 10)) [1 2 3]
。类似的宏->
,..
和doto
适用于不同的情况。
答案 3 :(得分:0)
如果您在vim中编写代码,请将以下代码放在等效于~/.vim/after/syntax/clojure.vim
的位置,然后通过将conceallevel
设置为2来隐藏:
syntax keyword clojureFunc partial conceal cchar=$
这会缩短阅读器和写入器在屏幕上的partial
,但不会给其他人带来麻烦。
我使用此技巧在大多数语言中创建速记符号(例如,在许多语言中,希腊字母lambda都隐含了匿名函数关键字-fn,lambda等)。