【问题标题】:Set sequencing type puzzle设置排序类型谜题
【发布时间】:2013-05-31 13:21:32
【问题描述】:

昨晚在回复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 的超类型之一和使sequenceU 工作的Unapply 机器之间的某些交互有关,当我能找到几分钟的时间时,我正计划工作通过类型并写下正在发生的事情的描述。

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

【问题讨论】:

    标签: scala types scalaz scalaz7


    【解决方案1】:

    哇,是的。这是我可以推测正在发生的事情。由于 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 是为 * 类型定义的,而 applicative 是为 * -> * 类型定义的,所以 Monoid 中 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 被(ab)用作总和:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-18
      • 1970-01-01
      • 2013-09-14
      • 2011-01-28
      • 1970-01-01
      相关资源
      最近更新 更多