2016-03-04 83 views
0

我试图创建斯卡拉这个功能,但我不肯定是否我做的方式是正确的。我觉得我完全迷失了。我需要帮助。如何创建一个附加功能

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

结果应该是一个新的类列表集合(具有与alist1和alist2相同的类型),其中依次包含alist1的元素,然后是alist2的 元素。 即,在链表,追加(alist1,alist2)应该表现在simlar到 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

什么'foldRight'?你实现了它? – mfirry

+0

什么是'x'?用于什么? – mfirry

+0

哇。上次编辑完全令人惊讶 – Odomontois

回答

1

所以,想象一下你有基地一些斯卡拉收集风格抽象特质像前置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 

UPDATE: 如果您不能修改您的抽象类型仍可以移动操作添加到一些隐含的包装保持了语法:

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) 
} 
0

你已经宣布在结构上的一些方法(的isEmpty,利弊,头,尾),利用他们,我会写水木清华这样的:

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)) 
}