2016-10-17 17 views
3

"Functional Programming in Scala"の本を進めています。私はそれがコンパニオンオブジェクトの一部であるべきと仮定scalaエラー "パターンタイプが予想されたタイプと互換性がありません"

def headOption: Option[A] = this match { 
     case Empty => None 
     case Cons(h, t) => Some(h()) 
    } 

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

object Stream { 
    def cons[A](hd: => A, tl: => Stream[A]): Stream[A] = { 
    lazy val head = hd 
    lazy val tail = tl 
    Cons(() => head,() => tail) 
    } 

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

    def apply[A](as: A*): Stream[A] = 
    if (as.isEmpty) empty else cons(as.head, apply(as.tail: _*)) 

} 

次に、以下の定義が与えられます。次のコードで章5.2始まります。コンパイルエラーを直ちに取得しないようにするには、「headOption [A]」を追加します。しかし、結果を "オブジェクトストリーム"に含めると、 "パターンタイプが予期しないタイプと互換性がありません;見つかった:myPackage.Empty.type required:myPackage.Stream.type"に "Empty"の下線が表示されています。

私はここで少し失われています。私は間違って何をしていますか?

答えて

2

trait Stream[+A]の一部である必要があります。

ここでthisは、Stream(特性ストリームではないオブジェクト)を指します。 StreamEmptyとするか、Consとすることができます。したがって、thisのパターンマッチングは意味があります。

headOptionは、利用可能な場合はストリームの最初の要素を返します。

case object Empty extends Stream[Nothing] 

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

    sealed trait Stream[+A] { 
     def headOption: Option[A] = this match { 
     case Empty => None 
     case Cons(h, t) => Some(h()) 
     } 
    } 



    object Stream { 

     def cons[A](hd: => A, tl: => Stream[A]): Stream[A] = { 
     lazy val head = hd 
     lazy val tail = tl 
     Cons(() => head,() => tail) 
     } 

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

     def apply[A](as: A*): Stream[A] = 
     if (as.isEmpty) empty else cons(as.head, apply(as.tail: _*)) 


    } 

ScalaのREPL

scala> :paste 
// Entering paste mode (ctrl-D to finish) 

case object Empty extends Stream[Nothing] 

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

sealed trait Stream[+A] { 

    def headOption: Option[A] = this match { 
    case Empty => None 
    case Cons(h, t) => Some(h()) 
    } 

} 

object Stream { 

    def cons[A](hd: => A, tl: => Stream[A]): Stream[A] = { 
    lazy val head = hd 
    lazy val tail = tl 
    Cons(() => head,() => tail) 
    } 

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

    def apply[A](as: A*): Stream[A] = 
    if (as.isEmpty) empty else cons(as.head, apply(as.tail: _*)) 

} 

// Exiting paste mode, now interpreting. 

defined object Empty 
defined class Cons 
defined trait Stream 
defined object Stream 

scala> Stream.cons(1, Empty).headOption 
res0: Option[Int] = Some(1) 
+0

ありがとうございました!それをもう少し考えた後、私はなぜこのようにしなければならないのか理解しています。 – ettlich

関連する問題