在Clojure中是否有一种智能的方法来验证函数输入?

在Clojure中是否有一种智能的方法来验证函数输入?,clojure,validation,Clojure,Validation,我正在编写一个简单的掷骰子应用程序,我已经创建了主函数,但是我想知道是否有一种“智能”的方法来验证Clojure中的函数输入,而不是使用分支条件来验证输入?下面是我的函数的一个示例测试,我还必须测试n是否不是一个数字,以及另一个if或or,它感觉很混乱 另外,如果有人能指出一个更聪明的方法来实现这个功能,我将非常感谢任何反馈,这是我第一次尝试在功能上编程 (ns DiceRoller) (defn roll "rolls a specified number of n sided dice "

我正在编写一个简单的掷骰子应用程序,我已经创建了主函数,但是我想知道是否有一种“智能”的方法来验证Clojure中的函数输入,而不是使用分支条件来验证输入?下面是我的函数的一个示例测试,我还必须测试n是否不是一个数字,以及另一个if或or,它感觉很混乱

另外,如果有人能指出一个更聪明的方法来实现这个功能,我将非常感谢任何反馈,这是我第一次尝试在功能上编程

(ns DiceRoller)

(defn roll
"rolls a specified number of n sided dice "
([] (roll 1 6))
([number] (roll number 6))
([number n]
  (if-not number? number (throw (IllegalArgumentException. (str "incorrect input, integers only"))))
  (take number (repeatedly #(+ (rand-int n) 1)))
  )
)

大多数Clojure的态度是“假设你得到了正确的东西”。在这种情况下,如果您完全取出支票,用户最终将得到基本相同的异常。但是如果你真的想这样做,你应该正确地去做!现在,您的代码在每个输入上都会抛出一个异常,因为您缺少
(number?number)

当然有-您可以使用
:pre
断言来实现这一点

(defn some-fun [x]
  {:pre [(number? x)]}
  (foo x))
现在,如果向函数传递一个非数值参数
x
,就会得到assertionErrorassert failed:(number?x)


正如@amalloy已经指出的那样,检查输入是否是一个数字是没有用的,但是有很多完全有效的前提条件(以及关于这个问题的后条件)检查,您可能希望应用到您的函数中。您可以看到有关该主题的更多详细信息。

谢谢,我只是在发布此文章时将其作为示例,实际上没有调试或其他内容。我认为最好是优雅地失败,闭包是否具有内置的catch块功能?抛出自定义异常比“自动”更优雅的是什么当
反复
注意到
数字
不是数字时出现异常?@amalloy它让您有机会提供更有意义的错误消息。对于用户来说,这比期望他们对反复抛出的异常进行解码要好得多。“只要假设你得到了正确的东西”与防御性编程的概念相反。撇开态度不谈,这里的另一个答案显示了执行输入验证的惯用方法,这在很多情况下都很有用。我喜欢这样,但不是吗调用函数时必须使用try-catch,这让人感觉太像Java了。