Option [Int]的条件映射通过使用scalaz的函数对

Pet*_*ter 2 scala scalaz

我有一对,Option[Int]并希望找到这两个值中的最小值,如果它们都存在,否则只是其中之一.假设我有一个功能minOption:

def minOption(a: Option[Int], b: Option[Int]): Option[Int]
Run Code Online (Sandbox Code Playgroud)

我想要的是输入到输出的以下映射:

(Some(a), Some(b)) => Some(Math.min(a,b))
(Some(a), None) => Some(a)
(None, Some(b)) => Some(b)
(None, None) => None
Run Code Online (Sandbox Code Playgroud)

是否有捷径可寻?我无法想出使用嵌套模式匹配的明显方法.

我认为这应该是微不足道的scalaz,但我还不是很熟悉,也找不到办法.

ste*_*tew 6

对于标记有Tags.MinVal的东西,有一个半群,它选择最小值:

scala> import scalaz._ ; import Scalaz._ ; import Tags._
import scalaz._
import Scalaz._
import Tags._

scala> MinVal(3).some |+| MinVal(1).some
res0: Option[scalaz.@@[Int,scalaz.Tags.MinVal]] = Some(1)

scala> MinVal(3).some |+| none[Int @@ MinVal]
res1: Option[scalaz.@@[Int,scalaz.Tags.MinVal]] = Some(3)

scala> none[Int @@ MinVal] |+| none[Int @@ MinVal]
res2: Option[scalaz.@@[Int,scalaz.Tags.MinVal]] = None
Run Code Online (Sandbox Code Playgroud)

在上面,Int @@ MinVal是一个类型,它是一个Int"标记" 的子类型MinVal,它有助于选择正确的半群. MinVal(x: Int)返回带有类型的x Int @@ MinVal. x.some就像Some(x)除了类型Option而不是Some,这有助于类型推断(有一个Semigroup for Option,但不适用于Some),类似地none[T]返回None,但它的类型Option[T]代替None(有助于相同的原因,没有半群为没有,但有一个选项)

如果有两个以上,也许你有这些列表,你可以使用suml:

scala> List(MinVal(2).some, None, MinVal(3).some, None, MinVal(1).some).suml
res5: Option[scalaz.@@[Int,scalaz.Tags.MinVal]] = Some(1)
Run Code Online (Sandbox Code Playgroud)