【发布时间】:2016-05-29 09:32:40
【问题描述】:
我最近从 F# 中绕道使用 clojure,遇到了一个名为 cond 的宏。 下面是一个用法示例:
(cond
(= target (nth arr mid)) mid
(< target (nth arr mid)) (search left (- mid 1))
(> target (nth arr mid)) (search (+ mid 1) right)
(= left right) -1)
这在伪代码中意味着以下内容:
if target == arr.[mid] then return mid
if target < arr.[mid] then return (call search(left, mid-1))
if target > arr.[mid] then return (call search(mid+1, right))
if left == right then return -1
这只是一个二分搜索的例子,以防你想知道什么是左右和中间,但并不重要。
我试图在 F# 中找到类似的东西,但我找不到,所以我决定尝试为自己编写它。 我最终得到了这样的结果:
type condition = bool * int
let cond (conds: condition seq) =
conds |> Seq.pick(fun c -> if fst c then Some (snd c) else None)
cond [| ( (=) target arr.[mid], mid )
( (=) left right, -1 )
( (<) target arr.[mid], recSrch left (mid-1) )
( (>) target arr.[mid], recSrch (mid+1) right )
|]
这里的问题是我想在递归函数中使用它,并且因为 recSrch left (mid-1) 正在被立即评估,所以我最终陷入了无限循环。我希望仅在条件成立时对其进行评估。另外,表单仍然不像 Clojure 中那样干净。
有什么想法可以改进吗?
【问题讨论】:
-
对于我们这些不了解 Clojure 的人来说,您的问题非常不透明。
-
抱歉,我添加了一些伪代码以明确 clojure 代码的行为方式。
-
能否发下完整代码,包括
target、left、right。