Clojure 程序流-一次计算失败时退出操作
对不起,如果这个问题没有任何意义 我目前正在编写一个小应用程序,我想将一些函数“链接”在一起,形成一个更广泛的计算 例如,我有一个函数,它调用一个Web服务并返回一个Clojure 程序流-一次计算失败时退出操作,clojure,Clojure,对不起,如果这个问题没有任何意义 我目前正在编写一个小应用程序,我想将一些函数“链接”在一起,形成一个更广泛的计算 例如,我有一个函数,它调用一个Web服务并返回一个散列映射,或者nil,如果是一个错误或出现了问题。链中的下一个函数获取映射并进行进一步处理,然后将其传递给下一个函数…依此类推 问题是,如果第一个函数失败,它将把nil传递给下一个函数,这将抛出一个空指针(或其他什么),我甚至不希望它达到这个阶段。 换句话说,如果链中的一项失败,我希望整个计算失败 e、 g 问题是我不想一开始就用i
散列映射
,或者nil
,如果是一个错误或出现了问题。链中的下一个函数获取映射并进行进一步处理,然后将其传递给下一个函数…依此类推
问题是,如果第一个函数失败,它将把nil
传递给下一个函数,这将抛出一个空指针(或其他什么),我甚至不希望它达到这个阶段。
换句话说,如果链中的一项失败,我希望整个计算失败
e、 g
问题是我不想一开始就用if(nil?arg)
乱丢每个函数,理想情况下,我希望有一个抽象可以为我解决这个问题,但我并不真正了解Clojure中提供的功能
我正在考虑采用Scala风格的选项
类型,它可以是Some(value)
或None
,但我仍然需要在开始时对代码进行检查
任何想法或回复都将非常感谢,其中包括Scala调用的选项
的monad实现。它被称为maybe-m
,其工作原理是将nil
视为None
。您可以这样使用它:
(ns mulk.monads-test
(:refer-clojure)
(:use clojure.repl
clojure.algo.monads))
(defn function1 [x]
x)
(defn function2 [x]
(+ x 10))
(defn function3 [x]
(* x 2))
(defn calc-stuff [thing]
(domonad maybe-m
[x1 (function1 thing)
x2 (function2 x1)
x3 (function3 (+ x2 10))]
x3))
(calc-stuff 10) ;=> 60
(calc-stuff nil) ;=> nil
(chain "http://webservice.com" function1 function2 function3 function4)
clojure.contrib.core有一个
-?>
宏,它可以完全满足您的需要
请参见您可以定义一个助手函数,用于链接函数调用并检查其间的nil值:
(defn chain [v & functions]
(cond (nil? v) nil
(empty? functions) v
:else (recur ((first functions) v) (rest functions))))
那么就这样称呼它:
(ns mulk.monads-test
(:refer-clojure)
(:use clojure.repl
clojure.algo.monads))
(defn function1 [x]
x)
(defn function2 [x]
(+ x 10))
(defn function3 [x]
(* x 2))
(defn calc-stuff [thing]
(domonad maybe-m
[x1 (function1 thing)
x2 (function2 x1)
x3 (function3 (+ x2 10))]
x3))
(calc-stuff 10) ;=> 60
(calc-stuff nil) ;=> nil
(chain "http://webservice.com" function1 function2 function3 function4)
太棒了,这就是我一直在寻找的,看起来这个库中还有一些对我非常有用的抽象!啊哈!好东西。我想知道
-?>
宏是否实际上只是Matthias回答中描述的maybe-m
单子的包装器?不,实现是自包含的: