문제

Clojure의 무한 게으른 시퀀스에 메타 데이터를 추가하려고 할 때 스택 오버플로를 얻고 메타 데이터를 벗으면 잘 작동합니다. 왜 추가 하는가 with-meta 매크로 게으른 seq를 깨뜨 렸습니까?

먼저 아주 좋은 숫자의 무한 서열을 만듭니다.

(defn good []
  (lazy-seq 
    (cons 42
      (good))))

user> (take 5 (good))
(42 42 42 42 42)

그런 다음 Lazy-seq 인스턴스 각각에 메타 데이터를 추가하십시오.

(defn bad []
  (lazy-seq 
    (cons 42
      (with-meta 
       (bad)
       {:padding 4}))))


user> (take 5 (bad))
java.lang.StackOverflowError (NO_SOURCE_FILE:0)
  [Thrown class clojure.lang.Compiler$CompilerException]

메타 데이터를 한 수준으로 이동해보십시오.

(defn also-bad []
  (with-meta 
   (lazy-seq 
     (cons 42
       (also-bad)))
   {:padding 4}))

user> (take 5 (foo))
java.lang.StackOverflowError (NO_SOURCE_FILE:0)
  [Thrown class clojure.lang.Compiler$CompilerException]

다음은 유한 한 순서에 대한 메타 데이터의 예입니다.

(defn also-works []
     (lazy-seq 
       (cons 4 
         (with-meta 
          () 
          {:a 5}))))

user> (also-works)
(4)
user> (meta (rest (also-works)))
{:a 5}
user> 
도움이 되었습니까?

해결책

a LazySeq 전화하자마자 몸을 평가합니다 withMetaLazySeq. 당신은 당신의 게으름을 잃습니다.

public final class LazySeq extends Obj implements ISeq, List{
    ...
    public Obj withMeta(IPersistentMap meta){
        return new LazySeq(meta, seq());
    }
    ...
}

seq() 게으른 SEQ의 신체가 아직 평가되지 않은 경우 평가합니다. 위의 코드는 계속 호출합니다 with-meta 연속적인 게으른 seq에서 스택이 폭발 할 때까지 모두 평가합니다. 나는 현재 신체를 평가하지 않고 게으른 SEQ에 메타 데이터를 추가 할 수있는 방법이 없다고 생각합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top