具有多个值的Coproduct

时间:2018-04-01 12:03:04

标签: scala scalaz shapeless

我正在玩无形的Coproduct,但我不知道我是否使用错误但我不知道如何创建具有多个值的coProduct

拥有此代码

 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])
  }

如何使用Coproduct来创造姓名,年龄和性别的人?

问候。

1 个答案:

答案 0 :(得分:2)

Coproduct和product是根据类别理论的两个双重构造,但在编程方面可以简化为:

  • 产品包含所有的给定类型
  • coproduct实现了一个的给定类型

例如,由姓名,年龄和性别组成的人应使用产品类型进行模式管理。这是因为一个人包括姓名,年龄和性别; 所有这些类型是构建一个人所必需的。

副产品的示例可以是具有子类型关系的任何东西,例如Fruit可以是Apple,Banana或Orange。我们还经常将副产品用于可能失败的结果类型,例如:响应可以是成功也可以是失败。无论是和未来都是副产品的两个例子。

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

Some(Name(Paul))
None
None

这是因为你的人,你编码的方式,是姓名,年龄或性别。只有其中一个。然后你通过创建一个名字来创建一个Person实例,这很好,所以如果你打印这三个选项,你会看到名称选择器给你Some(名字(保罗)),而其他两个是空的。

如果您将Person编码为产品(通过异类列表实现无形),您将获得:

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中,我们可以使用诸如Either或通过子类型层次结构(例如特性Fruit通过案例类Apple,Banana等扩展)构建副产品,而产品通常仅通过案例类建模(在您的情况下它)将是case class Person(name: String, age: Int, sex: String)

在无形状中,副产品基本上可以被视为“具有任意数量的可能性而不仅仅是两个”,而产品被实现为异质列表,意思是“任意数量的值的集合,也可以是变化的类型”。

详细了解产品(又名“异类列表”)here以及关于副产品(又名“受歧视的工会”)here