2014-09-30 3 views
6

Diese nicht kompiliert und ich verstehe nicht, warum:Warum funktioniert das Mapping über einen HList von Option [T] nicht?

import shapeless._ 
import poly._ 

object option extends (Option ~> List) { 
    def apply[T](t: Option[T]) = t.toList 
} 

val simple = Some(1) :: Some("hello") :: Some(true) :: HNil 
val opts: List[Int] :: List[String] :: List[Boolean] :: HNil = simple map option 

Diese etwas überraschend, da dies nicht kompiliert:

import shapeless._ 
import poly._ 

object choose extends (Set ~> Option) { 
    def apply[T](s: Set[T]) = s.headOption 
} 

val sets = Set(1) :: Set("foo") :: HNil 
val opts: Option[Int] :: Option[String] :: HNil = sets map choose 
+0

Bitte sagen Sie, welchen Fehler Sie bekommen. Lass die vielen Leser (zu deinem einen Autor) nicht raten oder müssen sie ausführen. –

+0

@Paul Thx für den Vorschlag. Es ist ein gewisser Kompromiss zwischen Fragenpräzision (was die Chancen, dass jemand die Frage IMHO tatsächlich beantworten wird, erheblich verbessert) und der Bereitstellung von so viel Information wie möglich. Vielleicht wird SO eines Tages einen integrierten Compiler haben und wir werden das Beste aus beiden Welten haben (ganz zu schweigen von weniger Tippfehlern im Code). – jedesah

+2

Äh, nein, nicht in diesem Fall. Das Bereitstellen der Fehlermeldung ist ein paar zusätzliche Zeilen und stört nicht, was Sie bereits gesetzt haben. "kompiliert nicht" ist nur geringfügig schlechter als das berüchtigte "es funktioniert nicht" –

Antwort

6

Das Problem Ihre Benutzung Some ist statt Option. Der Compiler beschwert sich, dass er nichts finden kann, um eine Liste von Some s zu konvertieren, obwohl Ihr Option Mapper verwendet wird. Um dies zu beheben können Sie:

Ihre einfache Liste Konstruktion ändern Option verwenden statt Some:

object option extends (Option ~> List) { 
    def apply[T](t: Option[T]) = t.toList 
    } 

    val simple = Option(1) :: Option("hello") :: Option(true) :: HNil 
    val opts2: List[Int] :: List[String] :: List[Boolean] :: HNil = simple map option 

Verwenden Some als Typ Ihres Mapper:

object option extends (Some ~> List) { 
    def apply[T](t: Some[T]) = t.toList 
    } 

    val simple = Some(1) :: Some("hello") :: Some(true) :: HNil 
    val opts2: List[Int] :: List[String] :: List[Boolean] :: HNil = simple map option 

Oder zwingen, die Art der einfach zu Option:

object option extends (Option ~> List) { 
    def apply[T](t: Option[T]) = t.toList 
    } 

    val simple: Option[Int] :: Option[String] :: Option[Boolean] :: HNil = Some(1) :: Some("hello") :: Some(true) :: HNil 
    val opts2: List[Int] :: List[String] :: List[Boolean] :: HNil = simple map option 
Verwandte Themen