Scala 集合排序型拼图

Scala 集合排序型拼图,scala,types,scalaz,scalaz7,Scala,Types,Scalaz,Scalaz7,昨晚在回复时,我注意到以下几点: scala> val foo: Option[Set[Int]] = Some(Set(1, 2, 3)) foo: Option[Set[Int]] = Some(Set(1, 2, 3)) scala> import scalaz._, Scalaz._ import scalaz._ import Scalaz._ scala> foo.sequenceU res0: scala.collection.immutable.Set[In

昨晚在回复时,我注意到以下几点:

scala> val foo: Option[Set[Int]] = Some(Set(1, 2, 3))
foo: Option[Set[Int]] = Some(Set(1, 2, 3))

scala> import scalaz._, Scalaz._
import scalaz._
import Scalaz._

scala> foo.sequenceU
res0: scala.collection.immutable.Set[Int] = Set(1, 2, 3)
也就是说,如果
foo
是一组可选的整数,则排序将返回一组整数

这不是我最初期望的,因为排序a
F[G[a]
应该返回a
G[F[a]
(假设
F
是可遍历的,并且
G
)。不过,在这种情况下,
选项
层就消失了

我知道这可能与
Set
的一个超类型和
Unapply
使
sequenceU
工作的机器之间的某种交互有关,当我能找到几分钟的时间时,我计划对这些类型进行研究,并写下发生的事情的描述


不过,这似乎是一个潜在的有趣的小谜题,我想我会把它贴在这里,以防有人能抢先找到答案。

哇,是的。以下是我能猜测到正在发生的事情。由于Set本身没有Applicative,因此我们得到的是Monoid#Applicative实例:

scala> implicitly[Unapply[Applicative, Set[Int]]].TC
res0: scalaz.Applicative[_1.M] forSome { val _1: scalaz.Unapply[scalaz.Applicative,Set[Int]] } = scalaz.Monoid$$anon$1@7f5d0856
由于Monoid是为kind*类型定义的,applicative是为kind*->*类型定义的,因此applicative in Monoid sorta的定义使用类型lambda在忽略的类型参数中插入:

final def applicative: Applicative[({type λ[α]=F})#λ] = new Applicative[({type λ[α]=F})#λ] with SemigroupApply...
注意,
λ
的类型参数
α
被丢弃,因此当调用Applicative#point时,它变为幺半群#零,而不是幺半群[Set[Option[Int]],它是幺半群[Set[Int]]

larsh指出,这有一个有趣的副作用,就是将序列u(ab)用作总和:

scala> List(1,2,3).sequenceU
res3: Int = 6