2017-02-04 21 views
3

Я пытаюсь определить класс типа, что HList, L, содержит определенный тип, A.Типичный элемент, содержащий элемент в HList?

trait Contains[A] { 
    type Out 
} 
object Contains { 

    type Aux[A, O] = Contains[A] { type Out = O } 

    def contains[L <: HList, A] 
     (implicit ev: Contains.Aux[L, A]) = ev 

    implicit def containsInt[H, L <: HList, A] 
     (implicit ev: H == A): Contains.Aux[H :: L, A] = 
    new Contains[H :: L] { 
     type Out = A 
    } 
} 

Конечно, это не компилируется из-за ev: H == A.

Существует ли такой тип эквивалентного типа?

После того, как это работает, я бы ожидать, что следующие компиляции:

implicitly[Contains.Aux[Int :: HNil, Int]], так как есть в HList в Int.

Принимаю во внимание, что implicitly[Contains.Aux[String :: HNil, Boolean] не компилируется, так как нет Boolean на входе HList.

+0

Я думаю, что вы можете изменить тип доказательств в: неявных эв: H =: = A Вообще-то трудно получить этот тип Ограничение на работу –

+0

Я нашел эту ссылку для Shapeless good: https://github.com/underscoreio/shapeless-guide/blob/develop/dist/shapeless-guide.pdf –

+0

Я купил и прочитал большую часть этой прекрасной книги. Мне нужно перечитать его! –

ответ

2

Вы ищете shapeless.ops.hlist.Selector.

С Selector ваших примерами работают вот так,

scala> import shapeless._, ops.hlist._ 
import shapeless._ 
import ops.hlist._ 

scala> Selector[Char :: HNil, Char] 
res0: shapeless.ops.hlist.Selector[shapeless.::[Char,shapeless.HNil],Char] = [email protected] 

scala> Selector[Int :: Char :: HNil, Char] 
res1: shapeless.ops.hlist.Selector[shapeless.::[Int,shapeless.::[Char,shapeless.HNil]],Char] = [email protected] 

scala> Selector[Int :: HNil, Int] 
res2: shapeless.ops.hlist.Selector[shapeless.::[Int,shapeless.HNil],Int] = [email protected] 

scala> Selector[Boolean :: Char :: HNil, Int] 
<console>:18: error: Implicit not found: shapeless.Ops.Selector[shapeless.::[Boolean,shapeless.::[Char,shapeless.HNil]], Int]. You requested an element of type Int, but there is none in the HList shapeless.::[Boolean,shapeless.::[Char,shapeless.HNil]]. 
     Selector[Boolean :: Char :: HNil, Int] 
      ^

scala> Selector[Boolean :: Char :: HNil, Char] 
res4: shapeless.ops.hlist.Selector[shapeless.::[Boolean,shapeless.::[Char,shapeless.HNil]],Char] = [email protected] 

scala> Selector[Boolean :: Int :: Char :: HNil, Char] 
res5: shapeless.ops.hlist.Selector[shapeless.::[Boolean,shapeless.::[Int,shapeless.::[Char,shapeless.HNil]]],Char] = [email protected] 

scala> Selector[Int :: HNil, HNil] 
<console>:18: error: Implicit not found: shapeless.Ops.Selector[shapeless.::[Int,shapeless.HNil], shapeless.HNil]. You requested an element of type shapeless.HNil, but there is none in the HList shapeless.::[Int,shapeless.HNil]. 
     Selector[Int :: HNil, HNil] 
      ^