2012-11-03 50 views
1

我想写一个简单的计算器与加法,减法等。简单的计算器(加法功能输入)在Clojure

我的问题是与获取用户输入。如何将一串数值变成矢量?还有什么是编写程序的更好方法?

(ns scalc.core) 

(defn add 
    [numbers] 
    (println (apply + numbers))) 

(defn numchoose 
    [] 
    (println "What numbers?: ") 
    (let [numbers (read-line)] numbers)) 

(defn opchoose 
    [] 
    (println "What operation would you like to do?: ") 
    (let [operation (read-line)] 

    (if (= operation "add") 
     (do 
     (println "You chose to add.") 
     (let [numvect (numchoose)] 
       (add [numvect])))))) 


(defn -main 
    [& args] 

    (opchoose) 
    (numchoose)) 

这是错误:

~/clj/scalc 1/7 % lein trampoline run -m scalc.core 
What operation would you like to do?: 
add 
You chose to add. 
What numbers?: 
5 7 
Exception in thread "main" java.lang.ClassCastException: Cannot cast java.lang.String to java.lang.Number 
     at java.lang.Class.cast(Class.java:3005) 
     at clojure.core$cast.invoke(core.clj:318) 
     at clojure.core$_PLUS_.invoke(core.clj:927) 
     at clojure.lang.AFn.applyToHelper(AFn.java:161) 
     at clojure.lang.RestFn.applyTo(RestFn.java:132) 
     at clojure.core$apply.invoke(core.clj:601) 
     at scalc.core$add.invoke(core.clj:5) 
     at scalc.core$opchoose.invoke(core.clj:21) 
     at scalc.core$_main.doInvoke(core.clj:27) 
     at clojure.lang.RestFn.invoke(RestFn.java:397) 
     at clojure.lang.Var.invoke(Var.java:411) 
     at user$eval15.invoke(NO_SOURCE_FILE:1) 
     at clojure.lang.Compiler.eval(Compiler.java:6511) 
     at clojure.lang.Compiler.eval(Compiler.java:6501) 
     at clojure.lang.Compiler.eval(Compiler.java:6477) 
     at clojure.core$eval.invoke(core.clj:2797) 
     at clojure.main$eval_opt.invoke(main.clj:297) 
     at clojure.main$initialize.invoke(main.clj:316) 
     at clojure.main$null_opt.invoke(main.clj:349) 
     at clojure.main$main.doInvoke(main.clj:427) 
     at clojure.lang.RestFn.invoke(RestFn.java:421) 
     at clojure.lang.Var.invoke(Var.java:419) 
     at clojure.lang.AFn.applyToHelper(AFn.java:163) 
     at clojure.lang.Var.applyTo(Var.java:532) 
     at clojure.main.main(main.java:37) 

编辑:解决方案现在看起来是这样的:

(ns scalc.core) 

(defn add [numbers] 
    (reduce + numbers)) 

(defn numchoose [] 
    (let [nums (re-seq #"\d+" (read-line))] 
    (map #(Integer/parseInt %) nums))) 

(defn delegate [] 
    (println "What operation would you like to do?: ") 
    (let [operation (read-line)] 

    (when (= operation "add") 
     (println "You chose to add.") 
     (println "What numbers? ") 
     (add (numchoose))))) 

(defn -main 
    [& args] 

    (delegate)) 

回答

3

为了得到这些数字,你可以使用re-seq

(re-seq #"\d+" "123 456 789") => ("123" "456" 789") 

你stil我只有字符串而不是数字。您可以使用read-string来获取数字(read-string很方便,但在所有情况下都不安全。在这里我们确保这些字符串中只有数字,所以它很好)。

(read-string "5") => 5 

而不是(apply + numbers)你可以使用reduce(reduce + numbers),也是你的附加功能真的不应该打印任何东西(你应该尽可能地尝试从侧面effecty功能分开功能功能)。

这个(let [numbers (read-line)] numbers)等于(read-line)。不要过分复杂的事情!

而不是

(if (= operation "add") 
     (do ...)) 

你可以写

(when (= operation "add") 
    ...) 

when只是一个宏,当你不需要在你的IFS在其他情况下,这是有用的(它在条件后,包一切一个do,并且当条件评估为false时评估为零)。

+0

感谢您的详细解答!我修复了这个程序,并且还使用了(Integer/parseInt)将分隔的数字字符串转换为整数(http://stackoverflow.com/questions/4714923/convert-a-sequence-of-strings-to-integers- Clojure的)。 – Emil