gpt4 book ai didi

clojure - cli-tool : Avoiding nested if's 配置文件的验证过程

转载 作者:行者123 更新时间:2023-12-02 10:55:36 28 4
gpt4 key购买 nike

考虑这段相当嵌套的 clojure 代码,它描述了传递给命令行工具的 edn-config 文件的验证过程。

(defn -main [& [config-path]]
(if config-path
(if-let [content (read-file config-path)]
(if-let [raw-data (read-edn content)]
(if-let [parsed (parse raw-data)]
(start-processing parsed)
(error "parsing-error"))
(error "invalid-edn-format"))
(error "file-not-found"))
(error "no argument"))

注意:调用的函数是虚拟函数

这需要更少嵌套和更少命令的方式来做到这一点。您对这里有什么改进建议吗?

上面的函数实际上可以归结为4个验证函数,它们是链式调用的:(1) Argument-Check,(2) File-Read,(3) Parse-EDN,(4) Parse-Data 。它们处理“错误”的方式有所不同:对于 1 和 4,我使用 clojure.spec,因此 :clojure.spec/invalid 在失败时返回。当出现问题时,其他的(2 和 3)会抛出异常。这使得这里的抽象变得特别困难。

最佳答案

使用任一 monad。

首先,您需要修改函数以返回Either:

(require '[cats.monad.either :as either])

(defn assert-config-path-e [config-path]
(if config-path
(either/right config-path)
(either/left "no argument")))

(defn read-file-e [config-path]
;; interpret return value as error
(if-let [content (read-file config-path)]
(either/right content)
(either/left "file-not-found")))

(defn read-edn-e [content]
(try
(read-edn content)
(catch ...
;; interpret thrown exception as error
(either/left "invalid-edn-format"))))

(defn parse-e [raw-data]
(if-let [parsed (parse raw-data)]
(either/right parsed)
(either/left "parsing-error")))

Right 值表示计算成功,Left - 发生了错误。

之后使用do-notation/mlet组合所有内容:

(require '[cats.core :as cats])

(defn -main [& [config-path]]
(cats/mlet [_ (assert-config-path-e config-path)
content (read-file-e config-path)
raw-data (read-edn-e content)
parsed (parse-e raw-data)]
(cats/return (start-processing parsed)))

关于clojure - cli-tool : Avoiding nested if's 配置文件的验证过程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39206491/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com