通常在列表中查找最大项目

时间:2014-09-17 03:27:05

标签: scala haskell max

在Haskell中,我编写了一个函数,给定List of a,返回Maybe a

max' :: Ord a => [a] -> Maybe a
max' []     = Nothing
max' (x:xs) = Just $ foldr (\y acc -> if (y > acc) then y else acc) x xs

我怎么能在Scala中写这个?我不确定Scala中的Ord等价物。

2 个答案:

答案 0 :(得分:8)

您可以使用scalaz.Orderscala.math.Ordering

使用Scalaz:

def max[A](as: List[A])(implicit ord: Order[A]): Option[A] =
  as.foldLeft(None: Option[A]) {
    case (None, a) => Some(a)
    case (s @ Some(m), a) => if (ord.greaterThanOrEqual(m, a)) s else Some(a)
  }

def max[A](as: List[A])(implicit ord: math.Ordering[A]): Option[A] =
  as.foldLeft(None: Option[A]) {
    case (None, a) => Some(a)
    case (s @ Some(m), a) => if (ord.gteq(m, a)) s else Some(a)
  }

请注意,Scalaz为所有def maximum: Option[A]个实例定义Foldable

scala> import scalaz.syntax.foldable._
import scalaz.syntax.foldable._

scala> import scalaz.std.AllInstances._
import scalaz.std.AllInstances._

scala> List(1, 2, 3).maximum
res0: Option[Int] = Some(3)

标准库为所有集合定义def max: A,但它不安全:

scala> (Nil: List[Int]).max
java.lang.UnsupportedOperationException: empty.max
...

答案 1 :(得分:3)

直接翻译你的Haskell版本:

scala> def max[a](vs: List[a])(implicit ord: math.Ordering[a]): Option[a] = vs match {
     |   case Nil   => None
     |   case x::xs => Some(xs.foldLeft(x)(ord.max))
     | }
max: [a](vs: List[a])(implicit ord: scala.math.Ordering[a])Option[a]

scala> max(1::2::3::4::2::Nil)
res0: Option[Int] = Some(4)

scala> max[Int](Nil)
res1: Option[Int] = None

scala> max("abcdefg".toList)
res2: Option[Char] = Some(g)

或更可能的版本:

scala> def max[a <% math.Ordered[a]](vs: List[a]): Option[a] = vs match {
     |   case Nil   => None
     |   case x::xs => Some(xs.foldRight(x){ (v, r) => if(v > r) v else r })
     | }
max: [a](vs: List[a])(implicit evidence$1: a => scala.math.Ordered[a])Option[a]

scala> max(1.0::2.3::4.5::1.6::Nil)
res4: Option[Double] = Some(4.5)