2013-05-31 26 views
8

Ostatnia noc w reagowaniu na this question, zauważyłem następujące:Set sekwencjonowanie typu puzzle

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) 

Oznacza to, że jeśli foo jest opcjonalny zestaw liczb, sekwencjonowanie zwraca zbiór liczb całkowitych.

To nie jest to, czego oczekiwano na początku, ponieważ sekwencjonowanie F[G[A]] powinien zwrócić G[F[A]] (zakładając, że F jest przesuwny i Gis an applicative functor). W tym przypadku jednak warstwa Option po prostu znika.

wiem to chyba ma coś wspólnego z jakąś interakcję pomiędzy jednym z supertypes z Set i maszyn Unapply sprawia, że ​​sequenceU pracę, a kiedy znajdę kilka minut mam zamiar pracować przez rodzajów i pisać opis tego, co się dzieje.

Wydaje się jednak, że jest to potencjalnie interesująca łamigłówka i pomyślałem, że opublikuję ją tutaj, na wypadek, gdyby ktoś mógł mnie pokonać.

Odpowiedz

7

wow, tak. Oto, co mogę się domyślić. ponieważ zestaw nie posiada własnego aplikacyjnych, jesteśmy coraz monoid # aplikacyjny instancji zamiast:

scala> implicitly[Unapply[Applicative, Set[Int]]].TC 
res0: scalaz.Applicative[_1.M] forSome { val _1: scalaz.Unapply[scalaz.Applicative,Set[Int]] } = [email protected] 

Od monoid jest zdefiniowane dla typów rodzaju * i aplikacyjnych jest zdefiniowane dla typów rodzaju * -> * definicja aplikacyjnych w monoid jakoś kliny w ignorowane parametru typu użyciu lambda typu:

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

zauważysz, że parametr typu α z λ jest wyrzucane, więc kiedy aplikacyjnych punkt # nazywa, który staje monoid #zero, zamiast tego, że jest Monoidem [Set [Option [Int]]], jest to Monoid [Set [Int]].

larsh wskazuje, że ma interesujący efekt uboczny alllowing sequenceU się (AB) używany jako suma:

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