程序流程 - 如果一个计算失败,则退出操作

djh*_*rld 5 clojure

对不起,如果这个问题没有任何意义.

我目前正在编写一个小应用程序,我希望将一些函数"链接"起来,形成更广泛的计算.

因此,例如,我有一个函数调用web服务并返回hash-map一个结果,或者nil如果是错误或出错了.链中的下一个函数接受映射并进行一些进一步处理,然后将其传递给下一个函数......依此类推.

问题是,如果第一个函数失败,它将传递nil给下一个函数,并将抛出一个nullpointer(或其他),我不希望它甚至达到这个阶段.换句话说,如果链中的一个项失败,我希望整个计算失败.

例如

;successful computation = function1 returns W -> function2 returns X -> function3 returns Y -> function4 returns Z -> Z
;failed computation = function1 returns W -> function2 returns X -> function3 returns nil -> nil
(-> (function1 "http://webservice.com") (function2) (function3) (function4))
Run Code Online (Sandbox Code Playgroud)

事情是我不想if(nil? arg)在开始的时候乱扔我的每一个功能,理想情况下我想要一个可以照顾我的抽象,但我并没有真正了解Clojure中的可用内容

我正在考虑采用Scala样式Option类型,可以是Some(value)或者None我仍然需要在开始时使用这些检查来丢弃我的代码

任何想法或回复都会非常感激

Mat*_*ard 4

Clojure Contrib包含algo.monadScala 调用的 monad 的实现Option。它被称为并通过视为来maybe-m工作。你可以这样使用它:nilNone

(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
Run Code Online (Sandbox Code Playgroud)