Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 如何在Poly1中操作字段类型?_Scala_Shapeless - Fatal编程技术网

Scala 如何在Poly1中操作字段类型?

Scala 如何在Poly1中操作字段类型?,scala,shapeless,Scala,Shapeless,我想在带标签的泛型上使用无形状contrib(+scalaz)的序列,但首先我需要映射字段类型 在那个例子中有可能创建缺少的f函数吗 object TestLabelledGeneric { import shapeless._ import singleton._ val a = "name" ->> Option("hello") :: "y" ->> Option(1) :: HNil val b = Option("name" ->

我想在带标签的泛型上使用无形状contrib(+scalaz)的序列,但首先我需要映射字段类型

在那个例子中有可能创建缺少的f函数吗

object TestLabelledGeneric {

  import shapeless._

  import singleton._


  val a = "name" ->> Option("hello") :: "y" ->> Option(1) :: HNil

  val b = Option("name" ->> "hello") :: Option("y" ->> 1) :: HNil

  val f = ???

  val name = Witness('name); val age = Witness('age)

  def assertTypedEquals[A](expected: A, actual: A): Unit = assert(expected == actual)

  assertTypedEquals[b.type](b, a.map(f))


}
解决了,谢谢@travis brown

以下是在我的机器上运行的版本:

object TestLabelledGeneric {

  import shapeless._

  import singleton._

  val a = "name" ->> Option("hello") :: "y" ->> Option(1) :: HNil

  val b = Option("name" ->> "hello") :: Option("y" ->> 1) :: HNil

  import labelled.{ FieldType, field }

  object f extends Poly1 {
    implicit def kv[K, V]: Case.Aux[
      FieldType[K, Option[V]],
      Option[FieldType[K, V]]
      ] =
      at(_.map(field[K](_)))
  }

  // If I try to use Witness.`"name"`.T directly in Res, I have a "not accessible type" error
  val name = Witness.`"name"`
  val y = Witness.`"y"`
  type Res = Option[FieldType[name.T, String]] :: Option[FieldType[y.T ,Int]] :: HNil

  def assertTypedEquals[A](expected: A, actual: A): Unit = assert(expected == actual)

  assertTypedEquals[Res](b, a.map(f))
}

您想将
字段类型[K,选项[V]]
转换为
选项[FieldType[K,V]]]
FieldType[K,Option[V]]
Option[V]
的一个子类型,您可以使用
shapeless.labeled.field
V
转换为
FieldType[K,V]

然后您可以将此操作放入
Poly1

import shapeless._, labelled.{ FieldType, field }, syntax.singleton._

object f extends Poly1 {
  implicit def kv[K, V]: Case.Aux[
    FieldType[K, Option[V]],
    Option[FieldType[K, V]]
  ] =
    at(_.map(field[K](_)))
}
这并不能完全满足您的需要,因为
a.map(f)
的类型不是
b.type
(这是
b
的单例类型)。您可以确认它确实做了您想要的事情,不过:

scala> type Res =
     |   Option[FieldType[Witness.`"name"`.T, String]] ::
     |   Option[FieldType[Witness.`"y"`.T, Int]] :: HNil
defined type alias Res

scala> assertTypedEquals[Res](b, a.map(f))
是的,他们是一样的