我理解宏 - >在clojure中应用了给出的参数所提供的所有函数。但是,它似乎不适用于匿名函数(在clojure 1.3.0上)。例如:
user> (-> 4 inc inc dec)
5
可是:
user> (-> 4 #(+ % 1) #(- % 1) #(+ % 1))
返回错误:
clojure.lang.Symbol cannot be cast to clojure.lang.IPersistentVector
[Thrown class java.lang.ClassCastException]
如果有人知道解决方法会有所帮助。谢谢!
答案 0 :(得分:38)
您可以在Clojure宏中使用匿名函数。你遇到了问题,因为你遗漏了一些括号。 :)您的示例在下面编辑。
(-> 4 (#(+ % 1)) (#(- % 1)) (#(+ % 1)))
答案 1 :(得分:27)
(这是基于我在评论中发布的问题的answer。)
->
宏获取每个参数,必要时将其作为列表(将“原始”函数应用于无参数 - 将myfunc
转换为(myfunc)
),然后插入第一个参数将->
作为每个列表中的第二个参数。
所以(-> foo myfunc)
变为(-> foo (myfunc))
,大致为(myfunc foo)
。
这一点在docs for ->
。
匿名函数的问题在于它们是由读者宏生成的described here (scroll down)。这意味着#(...)
被转换(在正常的宏扩展之前)到(fn [...] ...)
。这很好,但是,关键的是,已经是一个列表。
所以宏认为匿名函数已经被应用,实际上它正在遇到一个函数定义(两个都是列表)。并添加“额外”的parens - 如上面在另一个答案中所述 - 将匿名函数应用于no args。
这种不直观的行为的原因是->
宏使用的dwim(do-what-what-mean-mean,not dwim-witted,尽管...)启发式,添加到允许你通过将它们包含在列表中来提供“裸”功能而不是要求你将它们应用于没有args,只是一个启发式 - 它只是测试一个列表 - 并且被创建的函数定义混淆了读者宏。
[我的脾气暴躁,->
实施得很差,应该拒绝所有“裸”功能,而只是接受功能应用;然后它会显得更加一致。如果没有,那么至少文档可以更清楚,解释将事物放在列表中的激励语义。]
答案 2 :(得分:2)
您的具体案例可以通过以下方式解决:
Private Sub Workbook_BeforeClose(Cancel As Boolean)
If ActiveWorkbook.Saved = True Then
Cancel = False
Else
Dim iReply As Byte, iType As Integer
Dim events As Boolean
Dim alerts As Boolean
events = Application.EnableEvents
alerts = Application.DisplayAlerts
Application.EnableEvents = False
Application.DisplayAlerts = False
StartQuestion:
' Define buttons argument.
iType = vbYesNo + vbQuestion + vbDefaultButton2
iReply = MsgBox("Would you like to save now?", iType)
Select Case iReply
Case Is = vbYes ' user chose Yes save current workbook
'The following statements shows the save as dialog box with default path
Set FileSaveName = Application.FileDialog(msoFileDialogSaveAs)
FileSaveName.InitialFileName = ThisWorkbook.Name
FileSaveName.FilterIndex = 2 'select to save with a ".xlsm" extension
FileSaveName.Title = "Save As ... "
intchoice = FileSaveName.Show
If intchoice = 0 Then
Else
FileSaveName.Execute
End If
If ActiveWorkbook.Saved = True Then
ActiveWorkbook.Close
Cancel = False
Else
GoTo StartQuestion
End If
Case Is = vbNo ' user chose No, don't save
ActiveWorkbook.Saved = True
ActiveWorkbook.Close
Cancel = False
End Select
Application.EnableEvents = events
Application.DisplayAlerts = alerts
End If
End Sub
其中线程第一个宏(-> 4 (+ 1) (- 1) (+ 1))
负责将上一步的结果作为第一个参数插入" current"功能
混淆起因于->
不是一个函数而是一个宏,并且在这种情况下对参数的处理方式非常不同,如其他答案所解释的那样。