2017-10-07 5 views
0

Eclipseでscalaワークシートで何かを試しています。これは出力を表示していないため、エラーまたは警告も表示されません。Scalaワークシートはこのコードでは機能しません。コンパイルエラーは表示されません

object stream { 
    println("Welcome to the Scala worksheet") 

    def cons[T](hd: T, t1: => Stream[T]): Stream[T] = new Stream[T] { 
    def head = hd 
    private var t1Opt: Option[Stream[T]] = None 
    def tail: Stream[T] = t1Opt match { 
     case Some(x) => x 
     case None => t1Opt = Some(t1); tail 
    } 
    } 

    def streamIncrementedby2(x: Int): Stream[Int] = x #:: streamIncrementedby2(x + 2) 

    val x = this.cons(-1, this.streamIncrementedby2(5)) 
    println(x.head) 

} 

私はcoureraのOdersky著コースに例をしようとしています:Scalaの機能設計week3ビデオを。興味深いことに、上記の例で、最初のprintln文の下のものをすべて削除すると、評価された出力が表示されます。

*******アップデート******** 他の読者を助けるために、私は上記のプログラムの訂正版を解答に基づいて投稿しています。

def cons[T](hd: T, t1: => Stream[T]) = new Stream[T] { 
    override def head = hd 
    override def isEmpty = false 
    private[ this ] var t1Opt: Option[Stream[T]] = None 
    def tailDefined: Boolean = true 
    override def tail: Stream[T] = t1Opt match { 
     case Some(x) => x 
     case None => {t1Opt = Some(t1); tail} 
    } 
    } 
+0

は、多分あなたはエラーを見ていませんか?私はこのエラーを受け取りました。エラー:不正な継承を密封されたクラスのストリームから取得しました。(あなたがアーカイブしようとしていることを記述していないので、回答を与える方法がわかりません) – Ossip

+0

メソッドconsを定義しようとしていますストリームと要素hdを生成し、要素をストリームの先頭にします。 – Rpant

+0

あなたの解決策は本当に質問に答えません。 Scalaワークシートが実際に動作していない場合は、エディタ内のコードを変更しても効果はありません。あなたはワークシートを修正するために何をしましたか?実際にワークシートが正しく機能していれば、質問のタイトルを修正する必要があります。壊れたワークシートを修正するための助けを求めている人は、あなたの質問/回答が参考になりますか? – jwvh

答えて

2

あなただけのストリームの一般的な要素ヘッドを作りたい場合は、あなたがcons

def streamIncrementedby2(x: Int): Stream[ Int ] = x #:: streamIncrementedby2(x + 2) 

val x = Stream.cons(-1, this.streamIncrementedby2(5)) 
println(x.head) 

と呼ばれるストリームパッケージ内の既存の方法を使用することができますそれは正常に動作します。しかし、独自のバージョンを作成したい場合は、より深く掘り下げなければなりません。次の関数の定義を使用することによって、あなたはここに

def cons[T](hd: T, t1: => Stream[T]): Stream[T] = new Stream[T] { ... 

重要なことは= new Stream[T]でない普通の関数、コンストラクタ作っています。したがって、適切なコンストラクタが必要とする多くのものを提供する必要があります。headtailisEmptyなどの抽象関数をオーバーライドし、必要な関数tailDefinedを提供する必要があります。

def classCons[ T ](hd: T, t1: => Stream[ T ]): Stream[ T ] = new Stream[ T ] { 

    override def isEmpty = false 
    override def head = hd 
    private[ this ] var tlVal: Stream[ T ] = _ 

    def tailDefined: Boolean = tlVal ne null 

    override def tail: Stream[T] = { 

     if (!tailDefined) 
      synchronized { 
       if (!tailDefined) 
        tlVal = t1 
      } 

     tlVal 
    } 
} 

inspiration

また、あなたのcons機能通常の関数ANGはコンストラクタいじりせずに同じ結果を得ることができます。

def funcCons[ T ](hd: T, t1: => Stream[ T ]): Stream[ T ] = { 

    if (t1.isEmpty) 
     Stream(hd) 
    else 
     hd #:: t1.tail 
} 

結果は同じです。

val ccStream = classCons(-1, this.streamIncrementedby2(5)) 
val ffStream = funcCons(-1, this.streamIncrementedby2(5)) 
println(ccStream.head) 
println(ffStream.head) 
// Result => -1 
// Result => -1 
+0

ありがとうございます。それは役に立ちました。上記の質問を解決策として更新しました。あなたのソリューションも機能しました。私は '[this]'が私的変数に本当に必要であることを認識しました。これがなければうまくいかないでしょう。なぜ、これが必要なのですか?また、オデスキー教授のアプローチでは、「オプション」の中でテールをラップしているところがあります。あなたのアプローチはより明確です。最後に、あなたのソリューションで= _を使うのは何ですか?申し訳ありません、まだ学習中です。 – Rpant

+1

'private [this]'はフィールドへのアクセスを制限するので、classの他のインスタンスはそれを変更できません。それは同期状態として使用されるので重要です。'var tlVal:Stream [T] = _'は' tlVal'を 'Stream [T]'のデフォルト値に初期化します。これは基本的にはnullです。値がnullの場合はオプションが使用されるため、安全対策になります。この例では重要ではありませんが、一般に、より制御されたコードにはnullの代わりにOptionを使用する方が良いです。 –

関連する問題