Сопоставление кортежей в бесформенном HList

Ты сделаешь

  import shapeless._ ; import poly._

  object fun extends (List ~>> (List, Int)) {
    override def apply[T](list: List[T]): (List, Int) = list -> list.size
  }

  println((List(1,2,3) :: List("a", "b", "c") :: HNil).map(fun))

чтобы сопоставить каждый подсписок с парой. Однако что, если элементы HList более сложные, как, например, кортежи? Естественная попытка

  object fun extends ((String -> List) ~>> (List, Int)) {
    override def apply[T](list: (String -> List[T])): (List, Int) = list -> list.size

отклоняется компилятором. Что вы делаете? Где этому научиться?


person Valentin Tihomirov    schedule 18.01.2016    source источник


Ответы (1)


import shapeless._
import poly._

object fun2 extends Poly1 {
  implicit def caseTuple[T] =
    at[(String, List[T])](x => (x._2.tail, x._1.toInt))
}

Затем:

println((("56", List(1,2,3)) :: ("78", List(4,2,3)) :: HNil).map(fun))

Или, если вы хотите сделать это с оригинальным ~>, это все еще возможно, но на мой вкус выглядит некрасиво:

object fun3 extends (({type L[T] = (String, List[T])})#L ~> ({type L[T] = (List[T], Int)})#L) {
  override def apply[T](f: (String, List[T])): (List[T], Int) = f match {
    case (str, list) => (list.tail, str.toInt)
  }
}

println((("56", List(1,2,3)) :: ("78", List(4,2,3)) :: HNil).map(fun3))

P.S. Также обратите внимание, что ваш пример кода не компилируется. Вы пропустили [T] в первой части, вам нужно использовать ~>, а String -> List — это неправильный тип в scala в последней части. List - это конструктор типа, а не тип, и вы не можете использовать его таким образом.

person Archeg    schedule 19.01.2016