Clojure中部分的简明语法

dem*_*emi 10 clojure partial-application pointfree

不久前学习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])
Run Code Online (Sandbox Code Playgroud)

真是太好了!有这样的事吗?是否有可能定义自定义阅读器宏?

tol*_*ius 6

匿名函数语法#(...)可以与您尝试执行的操作类似地使用:

user=> (map (comp (partial + 10) (partial * 2)) [1 2 3])
(12 14 16) 
Run Code Online (Sandbox Code Playgroud)

相当于:

user=> (map (comp #(+ 10 %) #(* 2 %)) [1 2 3])
(12 14 16)
Run Code Online (Sandbox Code Playgroud)

一个微小的区别%只是一个函数参数,在这种情况下是第一个和唯一的.

  • 如果有几个论点,差异不是很小.或者如果他们的数量在开发过程中发 (2认同)
  • 这是真的.以上只是为了说明单个参数的功能.与真实"玩"(申请..%&),[这里](http://fulldisclojure.blogspot.com/2009/12/how-to-write-clojure-reader-macro-part.html)是调整Clojure [代码]的危险例子,而[here](https://gist.github.com/liquidz/919875)是一个更温和的[宏]. (2认同)

Leo*_*hin 5

我非常喜欢你使用#[]文字的部分函数表示法的想法.不幸的是,Clojure不允许我们直接增强#()表示法,但我们可以为自己定义一个宏,就像#p部分应用程序一样.

鉴于你有一个功能

(defn partial-wrap
  [args]
  (concat '(partial) args))
Run Code Online (Sandbox Code Playgroud)

定义于myapp.core.您可以将以下条目添加到data_readers.clj类路径的顶部:

{p myapp.core/partial-wrap}
Run Code Online (Sandbox Code Playgroud)

(通常一个人应该在这里使用名称空间限定符号a/p,因为不合格的符号是为Clojure保留的.但是不合格的符号确实有用,你需要依赖Clojure在未来的版本中不覆盖它们).

这最终几乎可以满足您的要求:

(map (comp #p[+ 10] #p[* 2]) [1 2 3])
=> (12 14 16)
Run Code Online (Sandbox Code Playgroud)