对压缩的HLists进行映射

5

我正在尝试使用shapeless从两个HList中选择“非空”值:

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个回答

5
您很接近了,但是choose的定义略有不同:map需要一个Poly1而不是一个Poly2
您正在对元组hlist进行映射,因此您需要一个接受单个参数(一个元组)的多态函数。相反,您提供的是接受两个参数的多态函数。差异微妙,但确实存在。
这是一个可行的版本:
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情况。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接