Created
March 31, 2017 21:03
-
-
Save zainab-ali/ba2658d782cb326a697316310d131365 to your computer and use it in GitHub Desktop.
Zip record with tuples as values
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package foo | |
import shapeless._ | |
import shapeless.labelled.FieldType | |
import shapeless.ops.hlist._ | |
/** This example zips two hlists together based on their keys and part of their values | |
* | |
* | |
* A left HList of type FieldType[Key, (A, LB)] :: LTail is zipped with a right HList which contains FieldType[Key, (A, RB)] | |
* to produce a FieldType[Key, (A, (LB, RB))] | |
* | |
* The implicit cannot be found | |
*/ | |
trait Foo[L <: HList, R <: HList] { | |
type Out <: HList | |
} | |
object Foo { | |
type Aux[L <: HList, R <: HList, Out0 <: HList] = Foo[L, R] { type Out = Out0 } | |
implicit def base[R <: HList]: Aux[HNil, R, R] = ??? | |
/** Given a left HList of type FieldType[Key, (A, LB)] :: LTail | |
* and a right HList which contains FieldType[Key, (A, RB)] | |
* produce a FieldType[Key, (A, (LB, RB))] :: OutTail | |
*/ | |
implicit def recurse[Key, A, R <: HList, LB, RB, RTail <: HList, LTail <: HList, OutTail <: HList]( | |
implicit ev0: shapeless.ops.record.Selector.Aux[R, Key, (A, RB)], | |
ev1: FilterNot.Aux[R, FieldType[Key, (A, RB)], RTail], | |
ev2: Aux[LTail, RTail, OutTail] | |
): Aux[FieldType[Key, (A, LB)] :: LTail, R, FieldType[Key, (A, (LB, RB))] :: OutTail] = ??? | |
} | |
object TestFoo { | |
type Key | |
type ValueA | |
type ValueBL | |
type ValueBR | |
type HL = FieldType[Key, (ValueA, ValueBL)] :: HNil | |
type HR = FieldType[Key, (ValueA, ValueBR)] :: HNil | |
//it can be called explicitly | |
val f: Foo[HL, HR] = Foo.recurse[Key, ValueA, HR, ValueBL, ValueBR, HNil, HNil, HNil] | |
//all the required implicits can be found | |
the[shapeless.ops.record.Selector.Aux[HR, Key, (ValueA, ValueBR)]] | |
the[FilterNot.Aux[HR, FieldType[Key, (ValueA, ValueBR)], HNil]] | |
the[Foo.Aux[HNil, HNil, HNil]] | |
//but the implicit cannot be found | |
the[Foo[HL, HR]] | |
} | |
/** Strangely, it works without tuples | |
* This uses FieldType[Key, ValueL] instead of FieldType[Key, (ValueA, ValueL)] | |
*/ | |
trait Bar[L <: HList, R <: HList] { | |
type Out <: HList | |
} | |
object Bar { | |
type Aux[L <: HList, R <: HList, Out0 <: HList] = Bar[L, R] { type Out = Out0 } | |
implicit def base[R <: HList]: Aux[HNil, R, R] = ??? | |
implicit def recurse[Key, R <: HList, ValueL, ValueR, RTail <: HList, LTail <: HList, OutTail <: HList]( | |
implicit ev0: shapeless.ops.record.Selector.Aux[R, Key, ValueR], | |
ev1: FilterNot.Aux[R, FieldType[Key, ValueR], RTail], | |
ev2: Aux[LTail, RTail, OutTail] | |
): Aux[FieldType[Key, ValueL] :: LTail, R, FieldType[Key, (ValueL, ValueR)] :: OutTail] = ??? | |
} | |
object TestBar { | |
type Key | |
type ValueL | |
type ValueR | |
type HL = FieldType[Key, ValueL] :: HNil | |
type HR = FieldType[Key, ValueR] :: HNil | |
//no problem finding this | |
the[Bar[HL, HR]] | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment