11

乱数の遅延シーケンスを作成するにはどうすればよいですか?

私の現在のコード:

(import '(java.util Random))

(def r (new Random))
(defn rnd [_] 
    (.nextInt r 10))

(defn random-numbers [max] 
    (iterate #(.nextInt r max) (.nextInt r max)))

(println (take 5 (random-numbers 10)))

実行すると例外がスローされます。

(スレッド「メイン」での例外 clojure.lang.ArityException: 間違った数の引数 (1) が渡されました: user$random-numbers$fn at clojure.lang.AFn.throwArity(AFn.java:437) at clojure.lang. AFn.invoke(AFn.java:39) at clojure.core$iterate$fn__3870.invoke(core.clj:2596) at clojure.lang.LazySeq.sval(LazySeq.java:42) at clojure.lang.LazySeq.seq (LazySeq.java:60) at clojure.lang.RT.seq(RT.java:466) at clojure.core$seq.invoke(core.clj:133) at clojure.core$take$fn__3836.invoke(core. clj:2499) で clojure.lang.LazySeq.sval(LazySeq.java:42) で clojure.lang.LazySeq.seq(LazySeq.java:60) で clojure.lang.Cons.next(Cons.java:39) でclojure.lang.RT.next(RT.java:580) at clojure.core$next.invoke(core.clj:64) at clojure.core$nthnext.invoke(core.clj:2752) at clojure.clojure.core$fn__4990.invoke(core_print.clj:140) の core$print_sequential.invoke(core_print.clj:57) clojure.core$pr_on.invoke の clojure.lang.MultiFn.invoke(MultiFn.java:167) (core.clj:3264) で clojure.core$pr.invoke(core.clj:3276) で clojure.lang.AFn.applyToHelper(AFn.java:161) で clojure.lang.RestFn.applyTo(RestFn.java: 132) clojure.core$apply.invoke(core.clj:600) で clojure.core$prn.doInvoke(core.clj:3309) で clojure.lang.RestFn.applyTo(RestFn.java:137) で clojure. core$apply.invoke(core.clj:600) で clojure.core$println.doInvoke(core.clj:3329) で clojure.lang.RestFn.invoke(RestFn.java:408) で user$eval7.invoke(testing) .clj:12) で clojure.lang.Compiler.eval(Compiler.java:6465) で clojure.lang.Compiler.load(Compiler.java:6902) で clojure.lang.Compiler.loadFile(Compiler.java:6863) at clojure.main$load_script.invoke(main.clj:282) at clojure.main$script_opt.invoke(main.clj:342) at clojure.main$main.doInvoke(main .clj:426) で clojure.lang.RestFn.invoke(RestFn.java:408) で clojure.lang.Var.invoke(Var.java:401) で clojure.lang.AFn.applyToHelper(AFn.java:161) at clojure.lang.Var.applyTo(Var.java:518) at clojure.main.main(main.java:37) [終了コード 1 で 3.8 秒で終了]java:518) at clojure.main.main(main.java:37) [終了コード 1 で 3.8 秒で終了]java:518) at clojure.main.main(main.java:37) [終了コード 1 で 3.8 秒で終了]

私は状態を使用しているため、これは完全に間違ったアプローチですか。つまり、r は java.util.Random のインスタンスですか、それとも単純な構文エラーですか?

私は自分自身で clojure を勉強しているだけなので、ご容赦ください :) .

4

4 に答える 4

31

repeatedly関数を繰り返し実行し、結果を seq に収集するのに最適です

user> (take 10 (repeatedly #(rand-int 42)))
(14 0 38 14 37 6 37 32 38 22)

元のアプローチと同様に、 iterate は引数を取り、それを関数にフィードし、その結果を取り、同じ関数に戻します。使用している関数は引数を必要としないため、ここで必要なものはあまりありません。もちろん、その引数のプレースホルダーを指定して機能させることもできますが、repeatedlyその方が適している可能性があります。

(defn random-numbers [max]
  (iterate (fn [ignored-arg] (.nextInt r max)) (.nextInt r max)))
#'user/random-numbers

user> (println (take 5 (random-numbers 10)))
(3 0 0 2 0)
于 2012-07-30T23:40:57.240 に答える
6

一般的なガイドとして、Java のクラス/関数から始めないでください。最初に clojure.* の Clojure のコア関数と名前空間を見てください (そして、現在モジュラー リポジトリにある提供された名前空間を見てください: http://dev.clojure.org/display/doc/Clojure+Contribを参照してください)。rand-int 自体は、clojure-core ですぐに利用できます。では、乱数ヘルパーの検索をどのように開始するのでしょうか?

Clojure 1.3 以降では、clojure-repl 名前空間を「使用」して、便利な apropos 関数にアクセスできます (Unix/Linux の apropos コマンドと同じ精神で使用されます)。apropos は、これまでにロードされた名前空間で一致するすべての定義を返します。

user> (use 'clojure.repl)
nil
user> (apropos "rand")
(rand rand-int rand-nth)

clojure.repl の find-doc 関数も別の方法です。

もう 1 つの指針は、www.clojuredocs.org で検索することです。これには、clojure core および clojure.* の関数の使用例が含まれています。

于 2012-08-01T23:25:27.103 に答える