使用Cons运算符获取自定义特征

时间:2015-12-15 16:37:15

标签: scala pattern-matching

我有一个 MyStream -trait:

trait MyStream[+A] {
   def uncons: Option[(A, MyStream[A])]
   def isEmpty: Boolean = uncons.isEmpty
}
object MyStream {
   def empty[A]: MyStream[A] =
       new MyStream[A] { def uncons = None }
   def cons[A](hd: => A, tl: => MyStream[A]): MyStream[A] =
              new MyStream[A] { lazy val uncons = Some((hd, tl)) }
   def apply[A](as: A*): MyStream[A] = if (as.isEmpty) empty
                else cons(as.head, apply(as.tail: _*))
}

如何使用uncons运算符进行模式匹配,如:

    def takeWhile(f: A => Boolean): MyStream[A] = this match {
        case uncons(h,t) if f(h()) => cons(h(), t() takeWhile f)
        case _ => empty
    }

我是Scala的新手,所以我需要一点帮助。

谢谢!

1 个答案:

答案 0 :(得分:1)

这个怎么样:

trait MyStream[+A] {
  def uncons: Option[(A, MyStream[A])]

  def isEmpty: Boolean = uncons.isEmpty

  def takeWhile(f: A => Boolean): MyStream[A] = this match {
    case MyStream(h, t) if f(h) => MyStream.cons(h, t takeWhile f)
    case _ => MyStream.empty
  }

  @tailrec
  final def foldLeft[B](z: B)(op: (B, A) => B): B =
    this match {
      case MyStream(h, t) => t.foldLeft(op(z, h))(op)
      case _ => z
    }

  override def toString = this.foldLeft("") { case (acc, x) => acc + x }
}

object MyStream {
  def empty[A]: MyStream[A] =
    new MyStream[A] {
      def uncons = None
    }

  def cons[A](hd: => A, tl: => MyStream[A]): MyStream[A] =
    new MyStream[A] {
      lazy val uncons = Some((hd, tl))
    }

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

  def unapply[A](stream: MyStream[A]) = stream.uncons
}

object TestMyStream extends App {

  import MyStream._

  val s = cons(1, cons(2, cons(3, empty)))

  println("All: " + s)
  println("Take < 3: " + s.takeWhile(_ < 3))
}

打印:

All: 123
Take < 3: 12