Set sequence type puzzle

Last night, in response to this question , I noticed the following:

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) 

That is, if foo is an optional set of integers, then sequencing returns a set of integers.

This is not what I expected at the beginning, since the sequence F[G[A]] should return G[F[A]] (assuming that F is passing and G is an applicative functor ). In this case, the Option layer just disappears.

I know that this probably has something to do with some interaction between one of the Set supertypes and the Unapply machine that does the sequenceU work, and when I can find a few minutes, I plan to work through the types and write a description of what happens .

This seems like a potentially interesting little puzzle, and I thought I'd post it here if someone could defeat me before the answer.

+8
types scala scalaz scalaz7
source share
1 answer

Wow, yes. Here I can assume that this is happening. since Set does not have its own applicator, instead we get instead an instance of Application:>

 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 

Since the monoid is defined for types of the type *, and the applicative is defined for types of the type * → *, the definition of the applicative in monoid sorting wedges in the ignored type parameter using the lambda type:

 final def applicative: Applicative[({type λ[α]=F})#λ] = new Applicative[({type λ[α]=F})#λ] with SemigroupApply... 

Note that a parameter of type α of λ discarded, so when an applicative # point is called that becomes monoid # zero, instead of being a monoid [Set [Option [Int]]], it is a monoid [Set [Int]].

larsh points out that this has an interesting side effect of any sequence U like be (ab) used as the sum:

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

All Articles