Scala的haskell最后一种方法的实现

时间:2010-02-15 19:28:39

标签: scala functional-programming

我正在尝试在scala中做一些示例程序以更熟悉该语言,因为我正在尝试重新实现Haskell中的一些内置方法,我确信这些方法中的大多数也是在Scala也是,但这些只是为了我的练习。我想我可以发布一些代码片段(不是所有代码片段)来获得更好的处理方式并验证我对scala的理解。如果这不是做这些事情的地方,请告诉我。

这是我的scala实现,用于获取任何列表的最后一个元素。这是正确的做事方式吗?通过使用Any我是否丢失了列表中包含的对象的类型?这是scala中实现这种事情的方式吗?

  def getLast(xs: List[Any]): Any = xs match {
     case List()         => null
     case x :: List()    => x
     case _ :: ys        => getLast(ys) 
   }

2 个答案:

答案 0 :(得分:6)

参数化你的函数类型并使用“Nil”代替List(),如下所示:

  def getLast[T](xs: List[T]): T = xs match {
     case Nil         => null.asInstanceOf[T]
     case x :: Nil    => x
     case _ :: ys     => getLast(ys) 
   }

另外,请考虑让它返回选项类型:

  def getLast[T](xs: List[T]): Option[T] = xs match {
     case Nil         => None
     case x :: Nil    => Some(x)
     case _ :: ys     => getLast(ys) 
   }

用法:

  val listOfInts = List(1,2,3)
  assert(getLast(listOfInts).isInstanceOf[Int])

  val listOfStrings = List("one","two","three")
  assert(getLast(listOfStrings).isInstanceOf[String])

答案 1 :(得分:5)

首先,请避开null,尤其是null.asInstanceOf[T]。用原语观察危险:

scala> null.asInstanceOf[Int]
res19: Int = 0

scala> null.asInstanceOf[Boolean]
res20: Boolean = false

因此签名应该是List[T] => T,因此空迭代器上的last会引发异常:

def last[T](ts: List[T]): T = ts match {       
    case Nil => throw new NoSuchElementException
    case t :: Nil => t                          
    case t :: ts => last(ts)                    
}   

或者改为:List[T] => Option[T]

def lastOption[T](ts: List[T]): Option[T] = ts match {
    case Nil => None                                   
    case t :: Nil => Some(t)                           
    case t :: ts => lastOption(ts)                     
}

def lastOption1[T](ts: List[T]): Option[T] = ts.reverse.headOption

def lastOptionInScala28[T](ts: List[T]): Option[T] = ts.lastOption  // :)