2015-07-28 11 views

Odpowiedz

6

Tak bezkształtne może wiele zrobić!

import shapeless._ 
    import syntax.std.tuple._ 

    trait basicOption extends Poly1 { 
    implicit def default[T] = at[T](t => Some(t)) 
    } 

    object fullOption extends basicOption { 
    implicit def caseSome[T] = at[Some[T]](s => s) 
    implicit def caseNone = at[None.type](s => s) 
    } 

    println((Some(1),2,Some(3)).map(fullOption)) // (Some(1),Some(2),Some(3)) 
    println((Some(1),2,None).map(fullOption)) // (Some(1), Some(2), None) 

Więcej przykładów można sprawdzić ich github repo

To dla bezkształtnej 2.0 iw górę, jeśli używasz coś starszego można jeszcze zrobić, ale zamiast dzwonić map na krotki bezpośrednio musiałbyś przejść przez HList.

+1

dobra odpowiedź, a ty mnie (i @travisbrown) pokonać do niego :-) –

7

Tak to jest,

scala> import shapeless._, syntax.std.tuple._ 
import shapeless._ 
import syntax.std.tuple._ 

scala> :paste 
// Entering paste mode (ctrl-D to finish) 

object opt extends opt0 { 
    implicit def optId[T <: Option[_]] = at[T](identity) 
} 
trait opt0 extends Poly1 { 
    implicit def default[T] = at[T](Option(_)) 
} 

// Exiting paste mode, now interpreting. 

defined object opt 
defined trait opt0 

scala> (Some(1), 2, Some(3)) map opt 
res0: (Some[Int], Option[Int], Some[Int]) = (Some(1),Some(2),Some(3)) 

Zauważysz, że Some[Int] „s przy pierwszej i ostatniej pozycji zostały zachowane podczas gdy uniósł środkowy element jest wpisany jako Option[Int]. Pracowałem już z założenia, że ​​to, co rzeczywiście przeznaczone było coś takiego,

scala> (Option(1), 2, Option(3)) map opt 
res1: (Option[Int], Option[Int], Option[Int]) = (Some(1),Some(2),Some(3)) 
+0

ah +1 dla 't <: opcja [ _] 'znacznie ładniejsze niż moje brzydkie rozwiązanie :-) –