Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/17.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 - Fatal编程技术网

scala证据参数究竟是什么

scala证据参数究竟是什么,scala,Scala,我一直在试图找到什么是证据参数的权威定义,但对于解决“找不到类型为….的证据参数的隐式值”的情况毫无用处。请您提供一个很好的解释,说明什么是证据参数?语言规范在以下方面使用了术语“证据”: 方法或非特征类的类型参数A也可以具有一个或多个上下文边界A:T。在这种情况下,可以将类型参数实例化为任何类型S,在实例化点存在证据证明S满足约束T。此类证据由类型为T[S]的隐式值组成 使用这种语法糖,您可以得到规范称之为“证据参数”的合成参数。(请注意,这也涵盖了视图边界,我将尝试发布我自己的答案,稍后再进

我一直在试图找到什么是证据参数的权威定义,但对于解决“找不到类型为….的证据参数的隐式值”的情况毫无用处。请您提供一个很好的解释,说明什么是证据参数?

语言规范在以下方面使用了术语“证据”:

方法或非特征类的类型参数
A
也可以具有一个或多个上下文边界
A:T
。在这种情况下,可以将类型参数实例化为任何类型
S
,在实例化点存在证据证明
S
满足约束
T
。此类证据由类型为
T[S]
的隐式值组成


使用这种语法糖,您可以得到规范称之为“证据参数”的合成参数。(请注意,这也涵盖了视图边界
,我将尝试发布我自己的答案,稍后再进行改进。让我们从一个激励场景开始,但您可以跳到下面的TLDR,然后根据需要返回这里。)

在一种场景中,证据参数可以被视为一种从原始定义之外使用某些行为(方法)丰富类的方法

《伟大的邮报》的温和复述:

如果您以前还没有直观地编写过这样的代码,下面是正在使用的证据参数的代码演示

object EvidenceExample {

  // class with no methods
  case class Bar(value: String)

  // a trait the class Bar had not implemented
  trait WithFoo[A] {
    def foo(x: A): String
  }

  // object that attaches an implementation of the trait for Bar - for methods
  // willing to play along with this kind of trait attachment - see immediately below
  implicit object MakeItFoo extends WithFoo[Bar] {
    def foo(x: Bar) = x.value
  }

  // method willing to recognize anything as having trait WithFoo, 
  // as long as it has evidence that it does - the evidence being the previous object
  def callFoo[A](thing: A)(implicit evidence: WithFoo[A]) = evidence.foo(thing)
  
  callFoo(Bar("hi")) // and it works
}
你可能会自下而上阅读这些代码,从而意识到类
Bar
在其原始定义之外得到了丰富。然而,只有与取证仪式一起使用的函数才能将其视为丰富

这种模式几乎没有什么神奇之处——尽管这是一种独特的语言功能——包装器对象将特征与
Bar
相关联,而
callFoo
依赖于这种关联

我们甚至可以在没有隐式的情况下编写相同的模式,但是最后一行,调用该方法的那一行,将需要一个额外的参数―是否使用隐式的经济性―完全取决于您

您可以根据自己的意愿添加糖分或减少糖分,例如,这里有一个小的语法改进:

(此处仅修改了最后一个
def
,现在删除注释)

而且,不需要您使用字符串
证据
来命名任何东西。编译器只需知道这是一个证据参数,因为它在所有这些等效情况下都被使用


更一般地说,或者从词源上说,证据参数是一个“证据”类型的特定属性的参数,只要方法的签名表明这种要求,编译器就需要它(在另一个答案中,没有为类型
提供任何
的证据。Scala证据参数在隐式参数列表之前

def foo[A: M](implicit b: B): C
// expands to:
// def foo[A](implicit evidence$1: M[A], b: B): C
有关更多详细信息,请参阅规范。

这是一篇很好的短文:Great one@corn_dog。那篇文章真的很好。只是想…我们能不能不为同一个目的使用结构类型。不,一点也不,因为一个
Foo
s整数的方式可能与一个
Foo
s a
java.sql.Timestamp
的方式不同,所以你不能依赖一个特定的我thod形状。顺便说一句——尽管几乎所有关于该主题的资源都指向它,但后来被删除的引用!它真的只是一种约定,而不是烘焙到语言中吗?编译器错误使用该术语,而不是镜像参数名,并且在我的hat..Thank@matt-我不知道规范中使用了这个词。我现在已经详细阐述了这个词。诚然,我有时会觉得有点困惑,这与常规的隐式转换和丰富模式有何不同。一篇好的博客文章可能会以更具凝聚力的方式将它们联系在一起(我想说,在这些语言特性中重用现有语言标记的经济性可能是一个争论的话题,至少与下划线哲学是一致的)。一些不同之处在于,即使最终使用了某种转换,您也可以将其用作远离实际转换应用位置的约束。此外,您实际上不需要执行某些实际转换。请参见
@annotation.implicitNotFound(msg = "Oh noes! No type class for ${A}")
trait MyTypeClass[A]

trait Bar[A] {
  def baz(implicit evidence: MyTypeClass[A]): Unit
}
trait Test {
  def bar: Bar[Any]

  bar.baz
}
object EvidenceExample {

  // class with no methods
  case class Bar(value: String)

  // a trait the class Bar had not implemented
  trait WithFoo[A] {
    def foo(x: A): String
  }

  // object that attaches an implementation of the trait for Bar - for methods
  // willing to play along with this kind of trait attachment - see immediately below
  implicit object MakeItFoo extends WithFoo[Bar] {
    def foo(x: Bar) = x.value
  }

  // method willing to recognize anything as having trait WithFoo, 
  // as long as it has evidence that it does - the evidence being the previous object
  def callFoo[A](thing: A)(implicit evidence: WithFoo[A]) = evidence.foo(thing)
  
  callFoo(Bar("hi")) // and it works
}
object EquivalentEvidenceExample {

  case class Bar(value: String)

  // a trait the class Bar had not implemented
  trait WithFoo[A] {
    def foo(x: A): String
  }
  
  implicit object MakeItFoo extends WithFoo[Bar] {
    def foo(x: Bar) = x.value
  }
  
  def callFoo[A:WithFoo](thing: A) = implicitly[WithFoo[A]].foo(thing) // lightly sugared syntax, frankly only more confusing
  
  callFoo(Bar("hi"))
}
def foo[A: M](implicit b: B): C
// expands to:
// def foo[A](implicit evidence$1: M[A], b: B): C