前回はScalazのOptionはMonoidとしても使用できる事を説明しました。
scala> 1.some |+| 2.some res10: Option[Int] = Some(3) scala> 1.some |+| none res11: Option[Int] = Some(1) scala> none |+| 2.some res12: Option[Int] = Some(2) scala> none[Int] |+| none[Int] res14: Option[Int] = None scala> List(1.some, 2.some, 3.some, 4.some).sumr res32: Option[Int] = Some(10) scala> List(1.some, 2.some, none, 4.some).sumr res20: Option[Int] = Some(7)
Optionのコンテナ側の畳込み戦略はOR演算でした。この場合は、Noneでないものをすべて足し込むという振舞いになります。
短絡OR
コンテナ側の畳込み戦略として短絡評価も考えられます。
短絡評価では、最初に有効となった値が使用されます。
Scalazでは短絡評価のモノイド演算を行うOptionとしてFirstOptionを提供しています。OptionのfstメソッドでFirstOptionを取得できます。
scala> 1.some.fst res42: scalaz.FirstOption[Int] = Some(1)
FirstOption同士を演算子|+|でモノイド演算すると以下のように最初に登場したSomeが使用されます。
scala> 1.some.fst |+| 2.some.fst res15: scalaz.FirstOption[Int] = Some(1) scala> 1.some.fst |+| none.fst res44: scalaz.FirstOption[Int] = Some(1) scala> none.fst |+| 2.some.fst res45: scalaz.FirstOption[Int] = Some(2) scala> none[Int].fst |+| none[Int].fst res48: scalaz.FirstOption[Int] = None
短絡ORは畳込みで使用すると効果がみえてきます。いずれの場合も最初に登場した(先頭に近い)Someが使用されます。
scala> List(1.some, 2.some, 3.some, 4.some).map(_.fst).sumr res35: scalaz.FirstOption[Int] = Some(1) scala> List(1.some, 2.some, none, 4.some).map(_.fst).sumr res37: scalaz.FirstOption[Int] = Some(1) scala> List(none, 2.some, 3.some, 4.some).map(_.fst).sumr res36: scalaz.FirstOption[Int] = Some(2)
LastOption
短絡ORとは反対に、最後に登場したSomeを使いたいケースもあるかもしれません。Scalazはその用途に使用できるLastOptionを提供しています。
OptionのlstメソッドでLastOptionを取得できます。
scala> 1.some.lst res49: scalaz.LastOption[Int] = Some(1)
LastOption同士を演算子|+|でモノイド演算すると以下のように最後に登場したSomeが使用されます。
scala> 1.some.lst |+| 2.some.lst res18: scalaz.LastOption[Int] = Some(2) scala> 1.some.lst |+| none.lst res51: scalaz.LastOption[Int] = Some(1) scala> none.lst |+| 2.some.lst res52: scalaz.LastOption[Int] = Some(2) scala> none[Int].lst |+| none[Int].lst res53: scalaz.LastOption[Int] = None
LastOptionをsumrメソッドで使用すると以下の振舞いになります。いずれも最後のSomeが畳込み結果となります。
scala> List(1.some, 2.some, 3.some, 4.some).map(_.lst).sumr res38: scalaz.LastOption[Int] = Some(4) scala> List(1.some, 2.some, none, 4.some).map(_.lst).sumr res39: scalaz.LastOption[Int] = Some(4) scala> List(none, 2.some, 3.some, 4.some).map(_.lst).sumr res40: scalaz.LastOption[Int] = Some(4) scala> List(1.some, 2.some, 3.some, none).map(_.lst).sumr res41: scalaz.LastOption[Int] = Some(3)
諸元
- Scala 2.9.2
- Scalaz 6.0.4
0 件のコメント:
コメントを投稿