Поток программы - выход из строя при сбое одного вычисления - PullRequest
5 голосов
/ 14 ноября 2011

Извините, если этот вопрос не имеет никакого смысла.

В настоящее время я нахожусь в процессе написания небольшого приложения и хочу объединить в цепочку некоторые функции, которые образуют более широкие вычисления.

Так, например, у меня есть функция, которая вызывает веб-сервис и возвращает hash-map в результате или nil, если произошла ошибка или что-то пошло не так.Следующая функция в цепочке берет карту и выполняет дальнейшую обработку, а затем передает ее следующей функции ... и так далее.

Дело в том, что если первая функция завершится ошибкой, она передаст nil следующей функции, которая выдаст нулевой указатель (или любой другой), и я не хочу, чтобы он даже достиг этой стадии.Другими словами, я хочу, чтобы все вычисления потерпели неудачу в случае сбоя одного элемента в цепочке.

например,

;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))

Дело в том, что я не хочу засорять каждую из своих функцийс if(nil? arg) в начале, в идеале я бы хотел абстракцию, которая могла бы позаботиться об этом для меня, но я не совсем понял, что доступно в Clojure

Я думал о принятии стиля ScalaOption тип, который может быть Some(value) или None, но мне все равно нужно засорять мой код этими проверками в начале

Любые идеи или ответы будут действительно приветствоваться

Ответы [ 3 ]

4 голосов
/ 14 ноября 2011

clojure.contrib.core содержит макрос -?>, который делает именно то, что вы хотите.

См. http://clojuredocs.org/clojure_contrib/clojure.contrib.core/-_q%3E

4 голосов
/ 14 ноября 2011

Clojure Contrib algo.monad включает реализацию монады, которую Scala называет OptionОн называется 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
1 голос
/ 14 ноября 2011

Вы можете определить вспомогательную функцию для цепочки вызовов функций и проверки значений nil между:

(defn chain [v & functions]
  (cond (nil? v) nil
        (empty? functions) v
        :else (recur ((first functions) v) (rest functions))))

Затем вызвать ее так:

(chain "http://webservice.com" function1 function2 function3 function4)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...