2017-05-24 9 views
0

私はUnionHListという2つから作成しました。EFとしましょう。このUnionから、タイプEの新しいHListをお返しします。元のリストと同じ値を持っていますが、私は気にしない、私は実際には正しいタイプシェイプレス/スカラのUnionからSelectAllを取得

HListをしたいそれは必ずしも、私が欲しいのは1つの関数にまとめることができません。 def selectFromUnion[E <: HList, F <: HList](u: Union[E, F]): SelectAll[u.Out, E] = ???

誰かがそれをどのように実装できるか知っていますか?あるいは形のついていない人がすでにそれをすることがあれば?

EDIT:もっと正確なことができれば、元のHListのタイプが2 HListの連合であるという証明が必要です。私たちは、探して元の問題を単純化することができます。

implicit def selectFromUnion[E, T <: HList, F <: HList](implicit u: Union[E :: T, F]): Selector[u.Out, E] = ???

悲しいことに、私はまだ私はそれを行うことができる方法として、見当もつかない。

+1

「ユニオン」の意味は?あなたが書いたものは、形のないラベル付きの共産品のようには見えません。 'E'と' F'のちょうどのところに 'Either'のような意味がありますか?あるいは、 'E'と' F'の両方を持つ '(、)'のようなものでしょうか? –

+0

'Union'はここでは' shapeless.ops.hlist.Union'クラスのインスタンスです。私が形を持たないことに慣れていないので、おそらく - おそらく - 私は関数の署名で何かを忘れてしまったでしょうか? – Molochdaa

答えて

0

だから、私は自分のUnion(勝利のためにコピー/パスタ)を宣言することで、私の場合のために働く解決策を見つけたとSelectAllインスタンスを与える属性

trait SelectableUnion[L <: HList, M <: HList] extends DepFn2[L, M] with Serializable { 
    type Out <: HList 

    def selectL: SelectAll[Out, L] 

    def selectM: SelectAll[Out, M] 
    } 

    trait LowPriorityUnion { 
    type Aux[L <: HList, M <: HList, Out0 <: HList] = SelectableUnion[L, M] {type Out = Out0} 
    } 

    object SelectableUnion extends LowPriorityUnion { 
    def apply[L <: HList, M <: HList](implicit union: SelectableUnion[L, M]): Aux[L, M, union.Out] = union 

    // let ∅ ∪ M = M 
    implicit def hlistUnion[M <: HList]: Aux[HNil, M, M] = 
     new SelectableUnion[HNil, M] { 
     type Out = M 

     def apply(l: HNil, m: M): Out = m 

     override def selectL: SelectAll[M, HNil] = SelectAll.hnilSelectAll 

     override def selectM: SelectAll[M, M] = new SelectAll[M, M] { 
      override def apply(t: M): M = t 
     } 
     } 

    // let (H :: T) ∪ M = H :: (T ∪ M) when H ∉ M 
    implicit def hlistUnion1[H, T <: HList, M <: HList] 
    (implicit 
     u: SelectableUnion[T, M], 
     f: FilterNot.Aux[M, H, M] 
    ): Aux[H :: T, M, H :: u.Out] = 
     new SelectableUnion[H :: T, M] { 
     type Out = H :: u.Out 

     def apply(l: H :: T, m: M): Out = l.head :: u(l.tail, m) 

     override def selectL: SelectAll[::[H, u.Out], ::[H, T]] = new SelectAll[H :: u.Out, H :: T] { 
      override def apply(t: H :: u.Out): H :: T = (t.head) :: u.selectL(t.tail) 
     } 

     override def selectM: SelectAll[::[H, u.Out], M] = new SelectAll[H :: u.Out, M] { 
      override def apply(t: ::[H, u.Out]): M = u.selectM.apply(t.tail) 
     } 
     } 

    // let (H :: T) ∪ M = H :: (T ∪ (M - H)) when H ∈ M 
    implicit def hlistUnion2[H, T <: HList, M <: HList, MR <: HList] 
    (implicit 
     r: Remove.Aux[M, H, (H, MR)], 
     u: SelectableUnion[T, MR] 
    ): Aux[H :: T, M, H :: u.Out] = 
     new SelectableUnion[H :: T, M] { 
     type Out = H :: u.Out 

     def apply(l: H :: T, m: M): Out = l.head :: u(l.tail, r(m)._2) 

     override def selectL: SelectAll[::[H, u.Out], ::[H, T]] = new SelectAll[H :: u.Out, H :: T] { 
      override def apply(t: H :: u.Out): H :: T = (t.head) :: u.selectL(t.tail) 
     } 

     override def selectM: SelectAll[::[H, u.Out], M] = new SelectAll[H :: u.Out, M] { 
      override def apply(t: ::[H, u.Out]): M = r.reinsert(t.head, u.selectM(t.tail)) 
     } 
     } 
    } 

を追加して、あなたは書くことができます

def selectFromUnion[E <: HList, F <: HList](u: SelectableUnion[E, F]): SelectAll[u.Out, E] = u.selectL 
関連する問題