我正在尝试在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。
答案 0 :(得分:1)
因此,假设您有一些scala-collection样式抽象特征,其基本操作如 prepend , foldLeft 和相同类型的空集合。基于它们来定义reverse
和append
非常简单:
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))
}