压缩的HLists映射

时间:2016-09-04 22:09:25

标签: scala shapeless

我正在尝试使用无形来选择"非空"来自两个HLists的价值:

import shapeless.{ HNil, Poly2}

object choose extends Poly2 {
  implicit def caseInt =
    at[Int,Int]{
      case (_,n) if n > 0 => n
      case (o,_) => o
    }

  implicit def caseString  =
    at[String,String] {
      case (_,n) if n.nonEmpty => n
      case(o,_) => o
    }
}


val g = "a" :: "" :: 0 :: HNil
val h = "" :: "a"  :: 5 :: HNil

g.zip(h).map(choose)

我在丢失隐式映射器时遇到错误 如果我理解正确,我需要提供证据,证明zip的结果是可映射的,但我不知道该怎么做

1 个答案:

答案 0 :(得分:4)

您非常接近,但choose的定义略有错误:map需要Poly1而不是Poly2

你正在映射一个元组列表,所以你需要一个带有单个参数(一个元组)的多态函数。你提供的是一个带有两个参数的多态函数。差异是微妙的,但它就在那里。

这是一个有效的版本:

import shapeless.{ HNil, Poly1 }

object choose extends Poly1 {
  implicit def caseInt =
    at[(Int,Int)]{
      case (_,n) if n > 0 => n
      case (o,_) => o
    }

  implicit def caseString  =
    at[(String,String)] {
      case (_,n) if n.nonEmpty => n
      case(o,_) => o
    }
}

val g = "a" :: "" :: 0 :: HNil
val h = "" :: "a"  :: 5 :: HNil

g.zip(h).map(choose) // "a" :: "a" :: 5 :: HNil

正如您所看到的那样,诀窍是扩展Poly1而不是Poly2,并在元组上定义at个案例。