首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无形性:从辅助产品映射到不同的辅助产品

无形性:从辅助产品映射到不同的辅助产品
EN

Stack Overflow用户
提问于 2015-04-27 14:32:34
回答 3查看 1.5K关注 0票数 11

在下面的文章中,我尝试创建一个多态函数来将RawFeatureValue转换为RefinedFeatureValue

代码语言:javascript
复制
import shapeless._

object test {
  type RawFeatureValue = Int :+: Double :+: String :+: CNil
  type RefinedFeatureValue = Int :+: Double :+: CNil

  private object convert extends Poly1 {
    implicit def caseInt = at[Int](i => i)
    implicit def caseDouble = at[Double](d => d)
    implicit def caseString = at[String](s => s.hashCode)
  }

  val a = Coproduct[RawFeatureValue](12)
  val b: RefinedFeatureValue = a map convert
}

但是,结果类型是Int :+: Double :+: Int :+: CNil,它与RefinedFeatureValue不兼容。

代码语言:javascript
复制
[error]  found   : shapeless.:+:[Int,shapeless.:+:[Double,shapeless.:+:[Int,shapeless.CNil]]]
[error]  required: test.RefinedFeatureValue
[error]     (which expands to)  shapeless.:+:[Int,shapeless.:+:[Double,shapeless.CNil]]
[error]   val b: RefinedFeatureValue = a map convert
[error]                                  ^

我如何告诉无形者,这两个Ints应该被视为一个?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-04-29 13:47:21

要做到这一点,最简单的方法是将每个元素映射到目标协同产品中,然后统一结果:

代码语言:javascript
复制
import shapeless._

type RawFeatureValue = Int :+: Double :+: String :+: CNil
type RefinedFeatureValue = Int :+: Double :+: CNil

object convert extends Poly1 {
  implicit val caseInt = at[Int](Coproduct[RefinedFeatureValue](_))
  implicit val caseDouble = at[Double](Coproduct[RefinedFeatureValue](_))
  implicit val caseString = at[String](s =>
    Coproduct[RefinedFeatureValue](s.hashCode))
}

这项工作如预期的那样:

代码语言:javascript
复制
scala> val a = Coproduct[RawFeatureValue](12)
a: RawFeatureValue = 12

scala> val b: RefinedFeatureValue = a.map(convert).unify
b: RefinedFeatureValue = 12

scala> val c = Coproduct[RawFeatureValue]("foo")
c: RawFeatureValue = foo

scala> val d: RefinedFeatureValue = c.map(convert).unify
d: RefinedFeatureValue = 101574

这个解决方案并不坏,但是它看起来确实很有用,足以成为一个单一的操作。

票数 12
EN

Stack Overflow用户

发布于 2015-04-29 21:31:09

或者,Coproduct上的方法允许在没有Poly (如果实际用例允许的话)的情况下完成它--并且减少样板。让我们来定义

代码语言:javascript
复制
def refine(v: RawFeatureValue): RefinedFeatureValue =
  v.removeElem[String]
    .left.map(s => Coproduct[RefinedFeatureValue](s.hashCode))
    .merge

那你就可以

代码语言:javascript
复制
scala> val a = Coproduct[RawFeatureValue](12)
a: RawFeatureValue = 12

scala> refine(a)
res1: RefinedFeatureValue = 12

scala> val c = Coproduct[RawFeatureValue]("foo")
c: RawFeatureValue = foo

scala> refine(c)
res2: RefinedFeatureValue = 101574

这包括:

  • 一方面将RawFeatureValue拆分为String,另一方面将其余的元素(构成RefinedFeatureValue的元素)拆分为removeElem,然后返回Either[String, RefinedFeatureValue]
  • 映射到结果的左侧,将其转换并打包为RefinedFeatureValue
  • 并将生成的Either[RefinedFeatureValue, RefinedFeatureValue]合并到一个RefinedFeatureValue中。
票数 7
EN

Stack Overflow用户

发布于 2017-03-28 19:04:19

或者,如果没有设置多态函数,则可以在这个库中使用转换类型类:https://github.com/xdotai/typeless/

下面是一个转换类型类,它将一个辅助产品转换为另一个辅助产品的选项:https://github.com/xdotai/typeless/blob/master/src/main/scala/coproduct/convert.scala

添加到依赖项:

代码语言:javascript
复制
libraryDependencies += "ai.x" %% "typeless" % "0.2.5"

代码:

代码语言:javascript
复制
scala> import ai.x.typeless.coproduct.Convert.Ops
import ai.x.typeless.coproduct.Convert.Ops

scala> import shapeless._
import shapeless._

scala> type A = String :+: Double :+: CNil
defined type alias A

scala> type B = Double :+: String :+: List[Int] :+: CNil
defined type alias B

scala> Coproduct[A]("test").convert[B]
res0: Option[B] = Some(Inr(Inl(test)))
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29898637

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档