There is a semigroup for things tagged with Tags.MinVal which selects the minimum val:
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
In the above, Int @@ MinVal
is a type which is a subtype of Int
, which has been "Tagged" with MinVal
, which helps select the right semigroup. MinVal(x: Int)
returns x with the type Int @@ MinVal
. x.some
is like Some(x)
except the type is Option
instead of Some
, and this helps with type inference (there is a Semigroup for Option, but not for Some), similarly none[T]
returns None
, but its type is Option[T]
instead of None
(helpful for the same reasons, there is no Semigroup for None, but there is one for Option)
If there are more than two, perhaps you have a list of these, you can use suml
:
scala> List(MinVal(2).some, None, MinVal(3).some, None, MinVal(1).some).suml
res5: Option[scalaz.@@[Int,scalaz.Tags.MinVal]] = Some(1)