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 无形状:这两种实例派生方法之间有什么区别?_Scala_Typeclass_Shapeless_Deriving_Generic Derivation - Fatal编程技术网

Scala 无形状:这两种实例派生方法之间有什么区别?

Scala 无形状:这两种实例派生方法之间有什么区别?,scala,typeclass,shapeless,deriving,generic-derivation,Scala,Typeclass,Shapeless,Deriving,Generic Derivation,有人能解释一下这两种类型类实例派生方法(特别是选项[A])之间的区别吗 一, trait MyTrait[A]{…} 对象MyTrait扩展了低优先级{ //基本体的实例 } 特征低优先级扩展了低优先级{ final implicit def generic[A,H实际上,如果没有右侧和实际实现,很难说 从您提供的信息来看,这两个类型类的行为并不等同 例如,在第一种方法中,你考虑一些特殊的情况,所以理论上,你可能在不同的情况下重新定义一些一般的行为。 顺便说一下,选项[A]是一些[A]和无的副产

有人能解释一下这两种类型类实例派生方法(特别是选项[A])之间的区别吗

一,

trait MyTrait[A]{…}
对象MyTrait扩展了低优先级{
//基本体的实例
}
特征低优先级扩展了低优先级{

final implicit def generic[A,H实际上,如果没有右侧和实际实现,很难说

从您提供的信息来看,这两个类型类的行为并不等同

例如,在第一种方法中,你考虑一些特殊的情况,所以理论上,你可能在不同的情况下重新定义一些一般的行为。 顺便说一下,

选项[A]
一些[A]
无的副产品。type
List[A]
scala:[A]
Nil.type
)的副产品,有时为副产品派生类型类比为
选项[A]
(或
List[A]
)更容易。

“正确工作”是指“已编译”或“为某个简单用例工作”

您的两个示例都涉及泛型乘积类型,但不涉及泛型求和类型,因此不存在使用
Some[A]:+:None:+:CNil
派生出例如
Option[A]
的风险,这会造成一些歧义。因此(据我所知),您可以编写第二个版本,如:

trait MyTrait[A] {...}

object MyTrait extends LowPriority {
 // instances for primitives

// deriving instances for options from existing non-option instances
 final implicit def forOption[A](implicit instance: MyTrait[A]): MyTrait[Option[A]] = ??? 
}

trait LowPriority {
// <<<----
 final implicit def hcons[A, H <: HList](
    implicit gen: Generic.Aux[A, H],
    h: Lazy[MyTrait[H]]
  ): MyTrait[A] = ???

  final implicit val hnil: MyTrait[HNil] = ???

  final implicit def product[H, T <: HList](
    implicit h: Lazy[MyTrait[H]],
    t: Lazy[MyTrait[T]]
  ): MyTrait[H :: T] = ???
}
因此,使用
隐式def forOption[A](隐式实例:MyTrait[A]):MyTrait[Option[A]]
的任何解决方案都更简单、更可靠

根据您直接放入同伴低优先级的内容,可能需要也可能不需要:

  • 如果定义了副产品,则手动支持,例如,
    选项
    列表
    可能与不成形的派生产品冲突
  • 如果手动为其伴生对象中的某个类型实现了
    MyTrait
    隐式,那么它将具有与直接在
    MyTrait
    中隐式相同的优先级-因此,如果它可以使用shapeless派生,则可能会有冲突
出于这个原因,将无形状隐式放在
LowPriorityInflicits
中是有意义的,但将原语和列表、选项等的手动编解码器直接放在companion中是有意义的。也就是说,除非您在companion中定义了一些,例如
选项[String]
隐式,这可能与“
选项[A]冲突
带有隐式for
A


由于我不知道您的确切用例,我无法确定,但我可能会选择秒方法,或者最有可能的方法是我在上面的代码片段中实现的方法。

谢谢!关于第一个版本-我第一次在
doobie
项目中看到这一点,当时我试图了解它如何与Shapess()在那之后,我试图实现一些类似的东西,但对这种方法有一个特别的疑问,因为我从未在许多Shapess的示例/教程中看到过这一点。我认为在Doobie的例子中,这是需要的。在那里,“
Write[Option[a]]
from
Put[a]
“可能用于原语,而在
选项[H::T]
中添加值时,可用于在添加
选项[H]
(其中处理
null
不需要将整个最终结果置零)或非
选项
H
(例如,一个字段中的
null
可能不会导致整个
Repr
/
A
)。因此,我们在这里期望的行为是不同的。因此,这三个层是有意义的:如果您有
Put[A]
,请将其提升到
Write[Option[A]
(同伴),如果要处理非可选产品,请在任何字段上使用派生,如果存在
选项[a],则任何字段上的
null
都会导致错误(优先级较低)
如果
A
是产品类型,则可以处理
选项
字段上的null,但非可选字段上的
null
将是整个
A
None
(甚至更低优先级)。将EvenLower与Lower放在同一级别可能会导致
选项
派生冲突。谢谢!这对于理解没有问题至关重要,尽管这只是一个没有任何调查的猜测,所以不要将其视为一个确定的答案,更像是一个探索建议。谢谢!在我的情况下,它似乎会产生同样的结果
trait MyTrait[A] {...}

object MyTrait extends LowPriority {
 // instances for primitives
}

trait LowPriority {
// deriving instances for options from existing non-option instances
 final implicit def forOption[A](implicit instance: MyTrait[A]): MyTrait[Option[A]] = ??? // <<<----

 final implicit def generic[A, H <: HList](
    implicit gen: Generic.Aux[A, H],
    h: Lazy[MyTrait[H]]
  ): MyTrait[A] = ???

  final implicit val hnil: MyTrait[HNil] = ???

  final implicit def product[H, T <: HList](
    implicit h: Lazy[MyTrait[H]],
    t: Lazy[MyTrait[T]]
  ): MyTrait[H :: T] = ???
}
trait MyTrait[A] {...}

object MyTrait extends LowPriority {
 // instances for primitives

// deriving instances for options from existing non-option instances
 final implicit def forOption[A](implicit instance: MyTrait[A]): MyTrait[Option[A]] = ??? 
}

trait LowPriority {
// <<<----
 final implicit def hcons[A, H <: HList](
    implicit gen: Generic.Aux[A, H],
    h: Lazy[MyTrait[H]]
  ): MyTrait[A] = ???

  final implicit val hnil: MyTrait[HNil] = ???

  final implicit def product[H, T <: HList](
    implicit h: Lazy[MyTrait[H]],
    t: Lazy[MyTrait[T]]
  ): MyTrait[H :: T] = ???
}
class MyCustomType
object MyCustomType {
  implicit val myTrait: MyTrait[MyCustomType]
}
implicitly[Option[MyCustomType]]