如何创建追加功能

时间:2016-03-04 20:01:47

标签: scala function append

我正在尝试在scala上创建此函数,但我不确定我的做法是否正确。我想我完全迷失了。我需要帮助。

函数append(alist1,alist2),其中alist1和alist2是两个相同类型的列表式集合。

结果应该是一个类似于列表的新集合(与alist1和alist2的类型相同),其中包含alist1的元素,后跟     alist2的元素按顺序排列。     即,在链接列表上,append(alist1,alist2)应该以类似的方式运行     alist1 ++ alist2。

这是我到目前为止所拥有的

            def append [B :> A ]( alist1 : ListLike [B], alist2:ListLike[B]): ListLike [B] = (alist1,alist2) match {
case Nil => Nil
case hd1::tl1 = > hd1 :: tl1.append ( alist1) 
case hd2 ::tl2 => hd2 :: tl2.append(alist2)
        }

这是在SCALA。

2 个答案:

答案 0 :(得分:1)

因此,假设您有一些scala-collection样式抽象特征,其基本操作如 prepend foldLeft 相同类型的空集合。基于它们来定义reverseappend非常简单:

trait ListLike[+E, T[+X] <: ListLike[X, T]] {
  def +:[E1 >: E](x: E1): T[E1]

  def foldLeft[X](z: X)(f: (X, E) => X): X

  def empty: T[E]

  def reverse: T[E] = foldLeft(empty)((list, x) => x +: list)

  def ++[E1 >: E](that: T[E1]): T[E1] = reverse.foldLeft(that)((list, x) => x +: list)
}

让我们介绍一些具体的类型

sealed trait MyList[+E] extends ListLike[E, MyList] {
  def +:[E1 >: E](x: E1): MyList[E1] = MyCons(x, this)

  def empty = MyNil

  def foldLeft[X](z: X)(f: (X, E) => X): X = {
    def go(z: X, lst: MyList[E]): X = lst match {
      case MyNil => z
      case MyCons(x, next) => go(f(z, x), next)
    }
    go(z, this)
  }

  override def toString = foldLeft("MyList(")( _ + _ + ",") + ")"
}

case object MyNil extends MyList[Nothing]

case class MyCons[+E](elem: E, next: MyList[E]) extends MyList[E]

您现在可以验证

(1 +: 2 +: 3 +: MyNil) ++ (4 +: 5 +: MyNil) 

产生与

完全相同的东西(相同类型)
1 +: 2 +: 3 +: 4 +: 5 +: MyNil 

<强>更新: 如果您无法修改抽象类型,您仍然可以将移动操作添加到保留语法的隐式包装器中:

implicit class ListLikeOps[E, T[+X] <: ListLike[X, T] ](lst: ListLike[E, T]){
  def ++[E1 >: E](that: T[E1]): T[E1] = lst.reverse.foldLeft(that)((list, x) => x +: list)
}

答案 1 :(得分:0)

你已经在一个结构上声明了一些方法(isEmpty,cons,head,tail),使用它们我会像下面写的那样:

trait Appendable[A]{
  def head: A = ???
  def tail: Appendable[A] = ???
  def isEmpty: Boolean = ???
  def reverse: Appendable[A] = ???
}

object Appendable{
  def cons[A](a: A, appendable: Appendable[A]): Appendable[A] = ???

  def append[A](a1: Appendable[A], a2: Appendable[A]) = 
    appendHelper(a1.reverse, a2)

  private def appendHelper[A](a1: Appendable[A], a2: Appendable[A]): Appendable[A] =
    if(a1.isEmpty) a2
    else appendHelper(a1.tail, cons(a1.head, a2))
}