昨晚在回复this question时,我注意到以下情况:
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
是一组可选的整数,则对它进行排序会返回一组整数。
这不是我最初的预期,因为对F[G[A]]
进行排序应该返回G[F[A]]
(假设F
可以遍历并且G
is an applicative functor )。但在这种情况下,Option
图层就会消失。
我知道这可能与Set
的一个超类型和使Unapply
工作的sequenceU
机制之间的某些交互有关,当我能找到几分钟时我打算研究这些类型并写下正在发生的事情的描述。
这似乎是一个可能有趣的小谜题,我想我会在这里发布,以防有人可以打败我的答案。
答案 0 :(得分:7)
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是针对种类*定义的,因此针对类型类型定义了应用* - > *,Monoid sorta中Applicative的定义使用类型lambda:
在一个被忽略的类型参数中楔入final def applicative: Applicative[({type λ[α]=F})#λ] = new Applicative[({type λ[α]=F})#λ] with SemigroupApply...
请注意,α
的类型参数λ
被丢弃,因此当调用Applicative#point时,它变为Monoid#zero,而不是它是Monoid [Set [Option [Int] ]]]它是一个Monoid [Set [Int]]。
larsh指出,这有一个有趣的副作用,即所有的序列U被用作总和:
scala> List(1,2,3).sequenceU
res3: Int = 6