В Scala реализован последний метод haskell - PullRequest
3 голосов
/ 15 февраля 2010

Я пытаюсь сделать несколько примеров программ на scala, чтобы лучше познакомиться с языком. Для этого я пытаюсь повторно реализовать некоторые встроенные методы в Haskell. Большинство этих методов, я уверен, также реализованы в Скала тоже, но это только для моей практики. Я думаю, что могу опубликовать некоторые фрагменты кода (не все), чтобы получить лучший способ сделать что-то и проверить мое понимание scala. Поэтому, пожалуйста, дайте мне знать, если это не то место, где можно делать такие вещи.

Вот моя реализация scala для получения последнего элемента любого списка. Является ли это правильным способом сделать, используя Any, я теряю тип объекта, содержащегося в списке? Так ли это реализовано в Scala?

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

Ответы [ 2 ]

6 голосов
/ 15 февраля 2010

Параметризовать тип вашей функции и использовать «Nil» вместо List (), например:

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

Также рассмотрите возможность возврата типа Option:

  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])
5 голосов
/ 16 февраля 2010

Во-первых, избегайте 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  // :)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...