2012-07-11 94 views
6

我試圖用無定形來解決this problem。但是我出於某種原因無法映射到HList。我會讓代碼爲自己說話。無法在HList上映射

import shapeless._ 
import HList._ 

case class Foo(a: Option[Int], b: Option[Int]) 

val a = Foo(Some(3), None) 

val b = Foo(Some(22), Some(1)) 

implicit val fooIso = HListIso(Foo.apply _, Foo.unapply _) 

val mapper = new (({ type O2[+A] = (Option[A], Option[A]) })#O2 ~> Option) { 
    def apply[A](x: (Option[A], Option[A])): Option[A] = x._1.orElse(x._2) 
} 

fooIso.fromHList(fooIso.toHList(a).zip(fooIso.toHList(b)).map(mapper)) 

錯誤消息:

<console>:55: error: could not find implicit value for parameter mapper: shapeless.Mapper[java.lang.Object with shapeless.~>[[+A](Option[A], Option[A]),Option],shapeless.::[(Option[Int], Option[Int]),shapeless.::[(Option[Int], Option[Int]),shapeless.HNil]]] 
       fooIso.fromHList(fooIso.toHList(a).zip(fooIso.toHList(b)).map(mapper)) 
                     ^

爲什麼不能映射工作?

回答

10

有一個簡單的辦法:只需定義函數作爲object代替val

object f extends (({ type O2[+A] = (Option[A], Option[A]) })#O2 ~> Option) { 
    def apply[A](x: (Option[A], Option[A])): Option[A] = x._1 orElse x._2 
} 

(請注意,我命名,以避免與mapper隱含參數混亂的功能f代替mappermap

我不知道我可以幫助爲什麼 -at某些時候,我試圖找出爲什麼val不會爲這種事情在無形的工作細節,我不記得我有多遠。

+8

Poly1(以及〜>)的實現取決於能夠命名與被定義的函數類實體相對應的單例類型,因爲它正在被定義。在實體是一個對象的情況下,該過程順利進行,並且在創建穩定標識符的同時實例化該值;但在那些兩者分離的地方並不那麼順利(通過顯式的新實例化並通過val定義創建穩定的標識符)。這具有某種意義,但我無法指出證明規範中的文本... if任何人都可以,請讓我知道。 – 2012-07-11 23:25:15