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

Tej*_*eni 3 functional-programming scala

我试图在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) 
   }
Run Code Online (Sandbox Code Playgroud)

Mit*_*ins 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) 
   }
Run Code Online (Sandbox Code Playgroud)

另外,请考虑使其返回Option类型:

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

用法:

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

  val listOfStrings = List("one","two","three")
  assert(getLast(listOfStrings).isInstanceOf[String])
Run Code Online (Sandbox Code Playgroud)

  • 有点迂腐,但这个方法的名称应该是`last`,遵循Haskell约定,而不是`getLast`.在Scala中通常不鼓励使用`get`和`set`前缀. (3认同)

ret*_*nym 5

首先,避免null,特别是null.asInstanceOf[T].用原语观察危险:

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

scala> null.asInstanceOf[Boolean]
res20: Boolean = false
Run Code Online (Sandbox Code Playgroud)

因此签名应该是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)                    
}   
Run Code Online (Sandbox Code Playgroud)

或者改为: 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  // :)
Run Code Online (Sandbox Code Playgroud)