2016-08-01 6 views
2

스칼라 스트림을 가지고 놀고 있습니다. 다음은 주어진 숫자에서 시작하는 모든 정수의 스트림입니다.
함수에서 모든 호출을 추적하기 위해 println을 추가했습니다.스칼라 스트림 필터 동작

def from(n: Int): Stream[Int] = n #:: from({ println(n); n + 1 }) 

val nats = from(0)   //> nats : Stream[Int] = Stream(0, ?) 

nats.take(4).toList  //> 0 
          //| 1 
          //| 2 
          //| 3 
          //| res0: List[Int] = List(0, 1, 2, 3, 4) 

예상대로, 이것은 내 스칼라 워크 시트의 출력입니다. 그런 다음 모든 소수의 흐름을 만들었습니다.

def sieve(s: Stream[Int]): Stream[Int] = { 
    s.head #:: sieve(s.tail.filter({ println("---"); _ % s.head != 0 })) 
}       //> sieve: (s: Stream[Int])Stream[Int] 

val primes = sieve(from(2))//> primes : Stream[Int] = Stream(2, ?) 

primes.take(4).toList  //> 2 
          //| --- 
          //| 3 
          //| 4 
          //| --- 
          //| 5 
          //| 6 
          //| --- 
          //| res1: List[Int] = List(2, 3, 5, 7) 

여기에 질문이옵니다. 제 생각에는 약간의 변경을해야하는데, _ 자리 표시 자 대신에 x 매개 변수를 추가해야합니다. 놀랍게도 출력이 상당히 다릅니다.

def sieve(s: Stream[Int]): Stream[Int] = { 
    s.head #:: sieve(s.tail.filter(x => { println("---"); (x % s.head) != 0 })) 
}       //> sieve: (s: Stream[Int])Stream[Int] 

val primes = sieve(from(2))//> primes : Stream[Int] = Stream(2, ?) 

primes.take(4).toList  //> 2 
          //| --- 
          //| 3 
          //| --- 
          //| 4 
          //| --- 
          //| --- 
          //| 5 
          //| --- 
          //| 6 
          //| --- 
          //| --- 
          //| --- 
          //| res1: List[Int] = List(2, 3, 5, 7) 

왜 이러한 모든 반복이 발생하는지 이해할 수 없습니다. 명시 적 매개 변수를 사용하는 것이 잘못된 이유는 무엇입니까?

s.tail.filter( { println("---");  _ % s.head != 0 }) 
s.tail.filter(x => { println("--- " + x); (x % s.head) != 0 }) 

당신이 println 메소드 호출의 차이를 볼 수 있나요 :

답변

3

{ println("---"); _ % s.head != 0 }{ x => println("---"); x % s.head != 0 } 대신 { println("---"); x => x % s.head != 0 }의 줄임말이기 때문에 차이가 있습니다.

첫 번째 경우에는 println을 호출 한 다음 함수를 반환하므로 filter 호출 당 ---이 한 번 인쇄됩니다. 두 번째에는 필터링 할 스트림 요소 당 filter 호출 당 한 번입니다 (그리고 sieve이 재귀 적이며 스트림을 다시 필터링하기 때문에 출력의 각 요소에 대해 ---으로 끝납니다).

+0

설명 주셔서 감사합니다, 나는 차이점이 있어요. 반환 된 함수가 동일한 수를 더 많이 필터링해야하는 이유는 명확하지 않습니다. – freedev

+1

'{x => println (s "$"s.head} --- $ x ");를 쓰면 더 잘 볼 수 있습니다. x % s.head! = 0}'(다른 옵션의 경우와 유사하게, 각 인쇄 된 행에 대해 '필터'가 참조하는 것을 볼 수 있습니다.) –

+0

"... 반환 된 함수가 더 많은 시간을 걸러 낼 수 있습니다 ... "그것은 반환 된 함수이기 때문에가 아니라 필터가 익명 함수를 매개 변수로 사용하여 컬렉션 항목에 적용되기 때문입니다. 익명 함수 (x => ...)에는 _을 사용할 때 println. –

0

이의 두 경우 모두에서 체의 인수를 비교하자, 면밀한 관찰이?

이제

출력

First:   Second: 
//> 2   //> 2 
//| ---  //| --- 3 

결정적인 차이

:

println("---"  ) 
println("--- " + x) 
바로 대시 후 " "+x를 추가하는 두번째 경우

하고이 사건의 정확한 차이입니다.

+1

@pedrofurla, 출력 라인 수를 센다. – jwvh

+0

@pedrofurla 문제를 더 잘 설명하기 위해 질문을 업데이트했습니다. – freedev