gpt4 book ai didi

Scala PartialFunction 可以是 Monoid 吗?

转载 作者:行者123 更新时间:2023-12-03 21:17:10 25 4
gpt4 key购买 nike

我以为PartialFunction可以 Monoid .我的思维过程正确吗?
例如,

import scalaz._
import scala.{PartialFunction => -->}

implicit def partialFunctionSemigroup[A,B]:Semigroup[A-->B] = new Semigroup[A-->B]{
def append(s1: A-->B, s2: => A-->B): A-->B = s1.orElse(s2)
}

implicit def partialFunctionZero[A,B]:Zero[A-->B] = new Zero[A-->B]{
val zero = new (A-->B){
def isDefinedAt(a:A) = false
def apply(a:A) = sys.error("error")
}
}

但当前版本 Scalaz(6.0.4) 不包括在内。有什么不包括在内的原因吗?

最佳答案

让我们用不同的眼光来看待这个问题。
PartialFunction[A, B]同构于 A => Option[B] . (实际上,为了能够在不触发对 A 的评估的情况下检查它是否是为给定的 B 定义的,您需要 A => LazyOption[B] )

所以如果我们能找到一个 Monoid[A => Option[B]]我们已经证明了你的主张。

给定 Monoid[Z] , 我们可以形成 Monoid[A => Z]如下:

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))
}

那么,如果我们使用 Option[B],我们有什么 Monoid(s)?作为我们的 Z ? Scalaz 提供了三个。主实例需要 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)

但这并不是结合两个选项的唯一方法。如果这两个选项都是 Some,则不会附加这两个选项的内容。 ,我们可以简单地选择两个中的第一个或最后一个。两个触发这个,我们用称为标记类型的技巧创建了一个不同的类型。这在精神上类似于 Haskell 的 newtype .
scala> import Tags._
import Tags._

scala> Monoid[Option[Int] @@ First].append(Tag(Some(1)), Tag(Some(2)))
res10: scalaz.package.@@[Option[Int],scalaz.Tags.First] = Some(1)

scala> Monoid[Option[Int] @@ Last].append(Tag(Some(1)), Tag(Some(2)))
res11: scalaz.package.@@[Option[Int],scalaz.Tags.Last] = Some(2)
Option[A] @@ First ,通过它附加 Monoid , 使用相同的 orElse语义作为你的例子。

所以,把这一切放在一起:
scala> Monoid[A => Option[B] @@ First]
res12: scalaz.Monoid[A => scalaz.package.@@[Option[B],scalaz.Tags.First]] =
scalaz.std.FunctionInstances0$$anon$13@7e71732c

关于Scala PartialFunction 可以是 Monoid 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9067904/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com