2016-05-04 8 views
1

私はClojureとLispを初めて使いましたが、これまでのところこれまで好きでした。私は現在、lazy-seqとClojureが無限のシーケンスを定義する能力を理解しようとしています。私が実行した場合初級Clojurist遅延シーケンスエラー:ISeqの作成方法がわからない:java.lang.Long

(defn geometric 
    ([] geometric 1) 
    ([n] (cons n (lazy-seq (geometric (* n 1/2)))))) 

(geometric) 

私のREPLで期待どおりに、それは、1を返し、私は次のコードを持っています。

IllegalArgumentException Don't know how to create ISeq from: 
java.lang.Long clojure.lang.RT.seqFrom 

私は何を得ることを期待することは次のとおりです:

(1 1/2 1/4 1/8 1/16 1/32 1/64 1/128 1/256 1/512) 

は、なぜ私はこのエラーを取得しています、私は実行する場合は、

(take 10 (geometric)) 

は、私は次のエラーを取得しますか?私が正しく理解していれば、レイジーシーケンスに賛成できなければならず、再帰的に評価されたシーケンスの最初の10個の値を返すべきです。

答えて

2

あなたはあなたのコード内の小さなタイプミスがあります。この修正(geometric 1)なし

(defn geometric 
    ([] (geometric 1)) ;; notice the added parens around geometric 1 
    ([n] (cons n (lazy-seq (geometric (* n 1/2)))))) 

が働いていた実装が捨てた表現geometric(ちょうど関数値)を評価することであったので、その後、1式が評価され、関数結果として返されました(このarity関数本体の最後の式でした)。

は、今では期待通りに動作します。それは無限のシーケンスを評価しようとすると、あなただけのREPLで安全(geometric)を呼び出すことはできません

(take 1 (geometric)) 
;; => (1) 

(take 5 (geometric)) 
;; => (defn geometric 
    ([] geometric 1) 
    ([n] (cons n (lazy-seq (geometric (* n 1/2)))))) 

注意してください。

1

(geometric)は、シーケンスではなく数値1と評価されます。 (take 10 1)はあなたが今見ているのと同じエラーを出します。

(geometric 1)takeの2番目の引数に指定できるシーケンスを生成するので、(take 10 (geometric 1))を実行してみてください。

2

あなたの問題はここにある:

([] geometric 1) 

この式はgeometricが引数なしで呼び出された場合、二つのことが起こるだろう、ということを意味します

  1. シンボルgeometricが評価され、 geometric機能になります。
  2. 番号1が返されます。あなたはおそらく何を意味するのか

このでした:これは(geometric)を呼び出すと(geometric 1)を呼び出すことと同等であることを意味し

([] (geometric 1)) 

。あなたの例では、今、期待通りに動作します。私のお気に入りの機能の

(take 10 (geometric)) 
;=> (1 1/2 1/4 1/8 1/16 1/32 1/64 1/128 1/256 1/512) 
4

ワン:

iterateは機能 fx, (f x), (f (f x), (f (f (f x)))ここ

は、同じ機能を持つエレガントな実装である等の返却値 xをとります
(defn geometric [] 
    (iterate #(/ % 2) 1)) 

あなたの質問に直接答えはありませんが、うまくいけば有益です!

関連する問題