Scala中带尾函数的Max元素

Scala中带尾函数的Max元素,scala,recursion,functional-programming,Scala,Recursion,Functional Programming,我正在处理Coursera函数式编程课程的作业,我偶然发现了一些奇怪的东西。此问题要求您仅使用方法isEmpty、head和tail查找整数列表的最大值。我的解决方案是一个递归函数,如果没有更多元素,它将捕获一个不支持的操作异常。然而,解决方案似乎不起作用,我认为这是因为从未捕获异常 /** * This method returns the largest element in a list of integers. If the * list `xs` is empty it

我正在处理Coursera函数式编程课程的作业,我偶然发现了一些奇怪的东西。此问题要求您仅使用方法
isEmpty
head
tail
查找整数列表的最大值。我的解决方案是一个递归函数,如果没有更多元素,它将捕获一个
不支持的操作异常。然而,解决方案似乎不起作用,我认为这是因为从未捕获异常

  /**
   * This method returns the largest element in a list of integers. If the
   * list `xs` is empty it throws a `java.util.NoSuchElementException`.
   *
   * You can use the same methods of the class `List` as mentioned above.
   *
   * ''Hint:'' Again, think of a recursive solution instead of using looping
   * constructs. You might need to define an auxiliary method.
   *
   * @param xs A list of natural numbers
   * @return The largest element in `xs`
   * @throws java.util.NoSuchElementException if `xs` is an empty list
   */
  def max(xs: List[Int]): Int = 
  {
    def maxOfTwo(value1: Int, value2: Int) = {
      if(value1 > value2) value1
      else value2
    }
    println(xs.size)
    try { maxOfTwo(xs.head, max(xs.tail)) }
    catch { case noTail: UnsupportedOperationException => xs.head }
  }
当我使用下面的代码时,它只是将
不支持的操作异常
替换为
异常
一切都很正常。我是不是遗漏了什么

def max(xs: List[Int]): Int = 
  {
    def maxOfTwo(value1: Int, value2: Int) = {
      if(value1 > value2) value1
      else value2
    }
    println(xs.size)
    try { maxOfTwo(xs.head, max(xs.tail)) }
    catch { case noTail: Exception => xs.head }
  }

我认为这样会更好:

  def max(xs: List[Int]): Option[Int] = {
    @tailrec
    def go(l: List[Int], x: Int): Int = {
      l match {
        case Nil    => x
        case h :: t => if (x > h) go(t, x) else go(t, h)
      }
    }
    if (xs.isEmpty) None else Some(go(xs.tail, xs.head))
  }
结果类型为
选项
,因为列表可以为空

更新


当使用
UnsupportedOperationException
时,它会失败,因为当您尝试访问空列表的
xs.head
时,您还应该捕获
NoTouchElementException
。它与
异常
一起工作,因为它是这两个异常的基类

无法使用UnsupportedOperationException模式捕获java.util.NoTouchElementException。
顺便说一句,您的代码两次抛出异常。第二个异常是catch块抛出的,通过调用
xs.head

只考虑功能性如何

def sum(xs: List[Int]): Int = {
  if (xs.isEmpty) 0 else xs.head + sum (xs.tail)  
}

您应该添加
家庭作业
标签:@AlexCruise如果是一个甚至不再在会话中的MOOC,它真的算是家庭作业吗?是的,这很有效,但我更感兴趣的是为什么我的解决方案在我使用Exception时有效,而在我使用UnsupportedOperationException时失败。因为当你试图访问空列表的xs.head时,你还应该捕获java.util.NoSuchElementException。异常是两个基类,这就是它工作的原因。嗯,好的。我以为List.tail抛出了一个UnsupportedOperationException?
List.tail
抛出
UnsupportedOperationException
如果可遍历集合为空,但是
List.head
抛出
NoSuchElementException
并首先被调用。