Scala 多值余积

Scala 多值余积,scala,scalaz,shapeless,Scala,Scalaz,Shapeless,我正在玩Shapess的副产品,但我不知道我是否使用了错误的产品,但我不知道如何创建具有多个值的副产品 有这个代码吗 case class Name(value: String) case class Age(value: Int) case class Sex(value: String) type Person = Name :+: Age :+: Sex :+: CNil @Test def main(): Unit = { val person =

我正在玩Shapess的副产品,但我不知道我是否使用了错误的产品,但我不知道如何创建具有多个值的副产品

有这个代码吗

 case class Name(value: String)

  case class Age(value: Int)

  case class Sex(value: String)

  type Person = Name :+: Age :+: Sex :+: CNil

  @Test
  def main(): Unit = {
    val person = Coproduct[Person](Name("Paul"))
    println(person.select[Name])
    println(person.select[Age])
    println(person.select[Sex])
  }
如何使用副产品确定姓名、年龄和性别的人


关于。

副产品和产品是植根于范畴理论的两个双重结构,但在编程术语中可以简化为:

  • 产品包括所有给定类型的
  • 副产品具体化给定类型中的一个
例如,由姓名、年龄和性别组成的人员应使用产品类型进行建模。这是因为一个人由姓名、年龄和性别组成所有这些类型都是构建一个人所必需的

副产品可以是任何具有子类型关系的产品,例如水果可以是苹果、香蕉或桔子。我们还经常对可能失败的结果类型使用副产品,例如,响应可以是成功的,也可以是失败的。非此即彼和未来都是副产品的两个例子

你把事情搞混了,当你真的需要一个产品的时候,你建模了一个副产品(从语言语法的角度来看,完全正确)。如果您运行代码,您将看到

Some(Name(Paul))
None
None
这是因为你的人,你编码的方式,要么是名字,要么是年龄,要么是性别。只有一个。然后通过创建名称创建Person的实例,这很好,因此如果打印这三个选择,您将看到名称选择器为您提供了一些(name(Paul)),而其他两个为空

如果将此人编码为产品(在通过异构列表实现的无形状中),您将获得:

case class Name(value: String)
case class Age(value: Int)
case class Sex(value: String)

type Person = HNil

val person = Name("Paul") :: Age(32) :: Sex("Yes please") :: HNil

println(person) // Name(Paul) :: Age(32) :: Sex(Yes please) :: HNil
在普通的Scala中,我们可以使用诸如或通过子类型层次结构(例如,通过案例类Apple、Banana等扩展特征果)之类的构造对副产品进行建模,而产品通常只通过案例类进行建模(在您的案例中,它将是
案例类Person(姓名:String,年龄:Int,性别:String)

在shapeless中,副产品基本上可以被视为“任意数量的可能性,而不是仅仅两个”,而产品被实现为一个异构列表,这意味着“任意数量的值的集合,这些值也可以是不同类型的”


阅读更多关于产品(又名“异质列表”)和关于副产品(又名“歧视联盟”)的信息。

@paul很高兴我能帮上忙!我讨厌人们只是扔进一堆不起作用的代码,然后说“帮我弄明白”,但像你这样的概念性误解很容易纠正,但对提问者来说却很有好处,因为事情已经安排好了。如果你在这件事上遇到进一步的困境,请告诉我,我很乐意帮助你。干杯!