これについては別の光を照らしましょう。
PartialFunction[A, B]
はA => Option[B]
と同形です。私たちはあなたの主張を証明してきたMonoid[A => Option[B]]
を見つけることができるのであれば
(実際に、それは与えられたA
のために定義されている場合B
の評価をトリガすることなくチェックすることができるようにするには、A => LazyOption[B]
が必要です)。次のようにMonoid[Z]
考える
、我々はMonoid[A => Z]
を形成することができます。私たちはZ
としてOption[B]
を使用するのであれば
implicit def readerMonoid[Z: Monoid] = new Monoid[A => Z] {
def zero = (a: A) => Monoid[Z].zero
def append(f1: A => Z, f2: => A => Z) = (a: A) => Monoid[Z].append(f1(a), f2(a))
}
を、私たちはどのようなモノイド(複数可)を持っていますか? Scalazは3つを提供します。プライマリインスタンスにはSemigroup[B]
が必要です。
implicit def optionMonoid[B: Semigroup] = new Monoid[Option[B]] {
def zero = None
def append(o1: Option[B], o2: => Option[B]) = o1 match {
case Some(b1) => o2 match {
case Some(b2) => Some(Semigroup[B].append(b1, b2)))
case None => Some(b1)
case None => o2 match {
case Some(b2) => Some(b2)
case None => None
}
}
}
これを使用して
:
scala> Monoid[Option[Int]].append(Some(1), Some(2))
res9: Option[Int] = Some(3)
をしかし、それには2つのオプションを組み合わせるための唯一の方法ではありません。 2つのオプションの内容を両方ともSome
の場合に追加するのではなく、2つのオプションの最初または最後を選択するだけです。 2つはこれをトリガし、Tagged Typesと呼ばれる特殊なタイプのトリックを作成します。これはHaskellのnewtype
と似ています。それはMonoid
だを通じて追加
scala> import Tags._
import Tags._
scala> Monoid[Option[Int] @@ First].append(Tag(Some(1)), Tag(Some(2)))
res10: [email protected]@[Option[Int],scalaz.Tags.First] = Some(1)
scala> Monoid[Option[Int] @@ Last].append(Tag(Some(1)), Tag(Some(2)))
res11: [email protected]@[Option[Int],scalaz.Tags.Last] = Some(2)
Option[A] @@ First
、あなたの例と同じorElse
セマンティクスを使用しています。だから、
、すべて一緒にこれを置く:
scala> Monoid[A => Option[B] @@ First]
res12: scalaz.Monoid[A => [email protected]@[Option[B],scalaz.Tags.First]] =
[email protected]
を、私はあなたが 'Function1'が組成物の下でモノイドであることを知っていると仮定? –
@dcsobral 'Function1 [A、A]'、別名「Endo [A]」です。 – retronym