2015-07-24 21 views
6
case object Empty extends Stream[Nothing] 
case class Cons[+A](h:() => A, t:() => Stream[A]) extends Stream[A] 

sealed trait Stream[+A] { 

    def toList: List[A] = { 
    val buf = new collection.mutable.ListBuffer[A] 
    def go(s: Stream[A]): List[A] = s match { 
     case Cons(h, t) => 
     buf += h() 
     go(t()) 
     case _ => buf.toList 
    } 
    go(this) 
    } 

    def cons[A](hd: => A, tl: => Stream[A]): Stream[A] = Stream.cons(hd, tl) 

    def empty = Stream.empty 

    def unfold[A, S](z: S)(f: S => Option[(A, S)]): Stream[A] = f(z) match { 
    case Some((h,t)) => cons(h, unfold(t)(f)) 
    case None => empty 
    } 

    def take(n: Int): Stream[A] = unfold((this, n)) { 
    case (Cons(h, t), 1) => Some((h(), (empty, 0))) 
    case (Cons(h, t), n) if n > 1 => Some((h(), (t(), n-1))) 
    case (Empty, 0) => None 
    } 
} 

object Stream { 

    def cons[A](hd: => A, tl: => Stream[A]): Stream[A] = Cons(() => hd,() => tl) 

    def empty[A]: Stream[A] = Empty 

    val ones: Stream[Int] = Stream.cons(1, ones) 
} 

object StreamTest { 
    def main(args: Array[String]) { 

    //why compile error: forward reference extends over definition of value ones 
    /*val ones: Stream[Int] = Stream.cons(1, ones) 
    println(ones.take(5).toList)*/ 

    println(Stream.ones.take(5).toList) 
    } 
} 

neden derleme hatası uzanır ?: ileri referans değeri olanlar çifti nesne 'Akış' deScala ileri başvuru tanımındaki

tanımı boyunca uzanan, val olanlar: Akış [Uluslararası] = Stream.scons (1, olanları)

Tamam ama ana yöntemde, tamam değil (ama ... aynı sentetikler!)

+0

@mz Lütfen, ana yöntemdeki yorum işaretini (/ * * /) silin, '/ * val olanlar: Akış [Int] = Akış.şartları (1, olanlar) println (ones.take (5) .toList) */' – Curycu

cevap

7

Yerel val'ler üye değildir. bloklar halinde kısıtlama diğer tavsiyem in the spec here, ifadeli olduğu

object StreamTest extends App { 
    //def main(args: Array[String]) { 

    //why compile error: forward reference extends over definition of value ones 
    val ones: Stream[Int] = Stream.cons(1, ones) 
    println(ones.take(5).toList) 

    println(Stream.ones.take(5).toList) 
    //} 
} 

aynı etkiye sahiptir blokta, tembel val yapmak: test kodu için

, bunu.

+0

işe yarıyor! ana yöntem olmaksızın, StreamTest nesnesi çalışır ... belki de sebebi 'Uygulamayı genişletir'. tembel val 'yaklaşımı da iyi çalışıyor. blokta kısıtlama oldukça ilginçtir. Teşekkürler! – Curycu

+0

'App', başlatıcının' main''dan çalışmasına izin veriyor, ancak şablon semantiğini tutuyorsunuz. –

1

ileri referans bu satırda başvurulmaktadır Cons[+A]... içinde:

def cons[A](hd: => A, tl: => Stream[A]): Stream[A] = Cons(() => hd,() => tl) 

deneyin arkadaşı nesnesine

case object Empty extends Stream[Nothing] 
case class Cons[+A](h:() => A, t:() => Stream[A]) extends Stream[A] 

taşımak.

+0

'Boşalt, Nesneleri Nesne'ye Taşı' ve Cons => Stream.Cons ve Empty => Stream.Empty 'komutlarını derleyin. Ama hiçbir şey değişmez – Curycu