Clojure中partial的简明语法
不久前在学习Haskell时,我爱上了无点表示法和特别方便的部分函数应用程序——只需提供您知道的参数。在Clojure中,我一直使用Clojure中partial的简明语法,clojure,pointfree,partial-application,Clojure,Pointfree,Partial Application,不久前在学习Haskell时,我爱上了无点表示法和特别方便的部分函数应用程序——只需提供您知道的参数。在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提供一种特殊的语法会很好
请看示例代码:
; 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])
这太好了!有这样的东西吗?是否可以定义自定义读取器宏?匿名函数语法#(…)的使用方法与您尝试执行的操作类似:
user=> (map (comp (partial + 10) (partial * 2)) [1 2 3])
(12 14 16)
相当于:
user=> (map (comp #(+ 10 %) #(* 2 %)) [1 2 3])
(12 14 16)
一个小小的区别是%
,它只意味着函数参数,在本例中是第一个也是唯一的。我非常喜欢您使用#[]文字的部分函数表示法。
不幸的是,Clojure不允许我们直接增强#()符号,但我们可以为部分应用程序定义一个类似于#p
的宏
假设你有一个函数
(defn partial-wrap
[args]
(concat '(partial) args))
在myapp.core
中定义。
您可以将以下条目添加到类路径顶部的data\u readers.clj
:
{p myapp.core/partial-wrap}
(这里通常应该使用命名空间限定符号,如a/p
,因为非限定符号是为Clojure保留的。然而,非限定符号确实有效,您需要依赖Clojure,而不是在将来的版本中覆盖它们)
这最终允许您几乎完成您要求的操作:
(map (comp #p[+ 10] #p[* 2]) [1 2 3])
=> (12 14 16)
我发现有一种方法可以在我的问题中使用分部代码:(map#(+10(*2%))[1 2 3)
。使用->
宏:(map#(>%(*2)(+10))[1 2 3]
。类似的宏有->
、。
和doto
,适用于不同的情况。如果您在vim中编写代码,请将以下代码放在与~/.vim/after/syntax/clojure.vim
等效的代码中,并通过将隐藏级别设置为2来打开隐藏:
syntax keyword clojureFunc partial conceal cchar=$
这缩短了读者和作者在屏幕上的部分内容,但不会给其他人造成混乱
我使用这个技巧在大多数语言中进行速记(例如,匿名函数关键字fn,lambda,在许多语言中隐藏在希腊字母lambda后面的任何东西).如果有几个参数,或者它们的数量在开发过程中发生了变化,那么差别就不那么小了。这是真的。以上只是为了说明一个参数函数。使用实数(apply..%&)是调整Clojure[代码]的一个危险例子,而使用更温和的[宏]@tolitius噢哇!这是我需要的Disclojure链接。我很自豪Sean决定使用我提出的相同语法。@demi这不是有点过分了。如果你的目标是更简洁,为什么不定义宏,比如说扩展到部分的$
?然后你就可以编写($+AB…)
因此,使用宏只能生成3个字符,就像您想要的那样。*无点表示法:)无点表示法具有不同的meaning@demi:你应该试着编辑你的问题,让它更客观一点,少一点关于“好”和“好”。我觉得你的问题很有趣(因为我对Clojure知之甚少,但我知道它缺少read宏,这是用Common Lisp编写类似宏的方式),但它太固执己见了。在我写这篇文章的时候,已经有2票赞成关闭它,所以请注意。虽然它确实有一些缺点(没有名称空间的“p”和“#p[”是)“阅读障碍”),演示数据读取器的使用真的很酷。clj
。如果有部分和部分的速记符号就太好了。例如,#[]表示类似于#[inc second vector]的部分,也许~[]表示部分,这样就可以做#[~[+10]~[*2]]。我的代码库中充满了窃取位置的部分。最主要的是”增强“读者不会因为这些def compose[G[]](隐式G0:Foldable[G]):Foldable[({typeλ[α]=F[G[α]})#λ]…
:)而陷入黑暗面