2015-07-28 29 views

回答

6

是沒有形狀可以做很多!

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) 

更多的例子,你可以檢查自己的github repo

這是無形的2.0及以上,如果使用的是較舊的版本,你仍然可以做,但不是在元組調用map直接,你將有通過HList

+1

好答案,你打我(和@travisbrown)把它:-) –

7

是的,

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)) 

你會發現,在第一和最後一個位置Some[Int]的都被保存下來,而取消中間元素的類型爲Option[Int]。我的假設是你真正意圖是這樣的工作,

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

啊+1'T <:選項[ _]'比我醜陋的解決方案更漂亮:-) –