2015-07-24 10 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) 
    } 
} 

warum Kompilierungsfehler ?: Vorwärts-Referenz erstreckt sich über Definition von Wert diejenigenscala Vorwärts-Referenz erstreckt sich über Definition

in Paar Objekt 'Stream, val diejenigen: Strom [Int] = Stream.scons (1, ist) ist ok

aber in main-Methode, es ist nicht ok (aber ... gleiche Kunststoffe!)

+0

@mz lösche bitte Kommentarzeichen (/ * * /) in der Hauptmethode, '/ * val one: Stream [Int] = Stream.cons (1, Einsen) println (ones.take (5) .toList) */' – Curycu

Antwort

7

Lokale Werte sind keine Mitglieder.

Für Ihren Test-Code, dies zu tun:

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) 
    //} 
} 

Die Einschränkung in Blöcken in the spec here formuliert, wo die andere Beratung ist es eine faule val in dem Block zu machen, die die gleiche Wirkung hat.

+0

es funktioniert! Ohne Hauptmethode läuft das StreamTest-Objekt ... vielleicht ist der Grund dafür, dass die App erweitert wird, denke ich. 'Lazy Val' Ansatz funktioniert auch gut. Einschränkung in Block ist ziemlich interessant. Vielen Dank! – Curycu

+0

'App' lässt den Initialisierer von' main' laufen, aber Sie behalten die Template-Semantik. –

1

Die Vorwärts-Referenz ist in Cons[+A]..., die in dieser Zeile verwiesen wird:

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

Try

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

in das Begleitobjekt zu bewegen.

+0

Bewegen Sie' Empty, Cons' in 'Objekt Stream' und ändern Sie' Cons => Stream.Cons und Empty => Stream.Empty', um Kompilierungsfehler zu bekommen. Aber nichts ändert sich – Curycu

Verwandte Themen