带有隐式参数的Scala隐式错误

带有隐式参数的Scala隐式错误,scala,implicit,Scala,Implicit,我的档案里有以下内容 import cats._ import cats.syntax.all._ implicit val showPrimaryFieldSchema: Show[PrimaryFieldSchema] = pf => { s"PRIMARY_ID ${pf.fName} ${pf.fType.show}" } 当我写下以下内容时: implicit def showVertexSchema(implicit pShow:

我的档案里有以下内容

import cats._
import cats.syntax.all._

implicit val showPrimaryFieldSchema: Show[PrimaryFieldSchema] = pf => {
        s"PRIMARY_ID ${pf.fName} ${pf.fType.show}"
    }
当我写下以下内容时:

implicit def showVertexSchema(implicit pShow: Show[PrimaryFieldSchema], npShow: Show[NonPrimaryFieldSchema] ): Show[VertexSchema] = vSchema => {
        s"""VERTEX ${vSchema.vName} (${vSchema.pField.show}, ${vSchema.nPFields.map(np => npShow.show(np)).mkString(", ")}) WITH primary_id_as_attribute="FALSE""""
    }
我得到以下错误:

值显示不是com.elsevier.entellect.tigergraph.schemabilder.DataTypes.PrimaryFieldSchema的成员 [error]s“”“顶点${vSchema.vName}(${vSchema.pField.show},${vSchema.nPFields.map(np=>npShow.show(np)).mkString(“,”}),其主属性为“FALSE”

但是,以下代码起作用:

implicit def showVertexSchema(implicit pShow: Show[PrimaryFieldSchema], npShow: Show[NonPrimaryFieldSchema] ): Show[VertexSchema] = vSchema => {
        s"""VERTEX ${vSchema.vName} (${pShow.show(vSchema.pField)}, ${vSchema.nPFields.map(np => npShow.show(np)).mkString(", ")}) WITH primary_id_as_attribute="FALSE""""
    }
所以我真的想知道为什么

vSchema.pField.show
这里一点也不好<代码>隐式pShow:Show[PrimaryFieldSchema]是一个类别1隐式,是一个参数。所以我不确定

有人能解释一下吗

编辑1 然后我做了

implicit def showVertexSchema(implicit pShow: Show[PrimaryFieldSchema], npShow: Show[NonPrimaryFieldSchema] ): Show[VertexSchema] = vSchema => {

    implicit val showPrimaryFieldSchema1: Show[PrimaryFieldSchema] = pf => {
        s"PRIMARY_ID ${pf.fName} ${pf.fType.show}"
    }

    s"""VERTEX ${vSchema.vName} (${vSchema.pField.show}, ${vSchema.nPFields.map(np => npShow.show(np)).mkString(", ")}) WITH primary_id_as_attribute="FALSE""""
}
//> value show is not a member of A$A7.this.PrimaryFieldSchema

然后,如果我删除隐式值,但只保留参数,那么它当然可以作为一个魅力

似乎存在一个问题,即相同优先级的2个隐式变量可能在范围内

编辑3 我添加了下面的scalac选项,得到

toShow is not a valid implicit value for vSchema.pField.type => ?{def show: ?} because:
ambiguous implicit values:
 both lazy value showPrimaryFieldSchema in class A$A31 of type cats.Show[A$A31.this.PrimaryFieldSchema]
 and value pShow of type cats.Show[A$A31.this.PrimaryFieldSchema]
 match expected type cats.Show[A$A31.this.PrimaryFieldSchema]
    s"""VERTEX ${vSchema.vName} (${vSchema.pField.show}, ${vSchema.nPFields.map(np => npShow.show(np)).mkString(", ")}) WITH primary_id_as_attribute="FALSE""""

This is the kind of feedback i would expect per default. 

However is that correct, i do not really get the implicit resolution rule here. Doesn't precedence play ?

因为您有冲突的
Show[PrimaryFieldSchema]
Show[NonPrimaryFieldSchema]
隐含:

// if you will remote implicit here 
val showPrimaryFieldSchema: Show[PrimaryFieldSchema] = pf => {
    s"PRIMARY_ID ${pf.fName} ${pf.fType.show}"
}

// and also here
val showNonPrimaryFieldSchemaa: Show[NonPrimaryFieldSchema] = pf => {
    s"${pf.fName} ${pf.fType.show}"
}

// Another working version
//implicit def showVertexSchema(implicit pShow: Show[PrimaryFieldSchema], npShow: Show[NonPrimaryFieldSchema] ): Show[VertexSchema] = vSchema => {
//    This works because you are using `pShow` explicetly, so no conflict.
//    s"""VERTEX ${vSchema.vName} (${pShow.show(vSchema.pField)}, ${vSchema.nPFields.map(np => npShow.show(np)).mkString(", ")}) WITH primary_id_as_attribute="FALSE""""
//}


implicit def showVertexSchema(implicit pShow: Show[PrimaryFieldSchema], npShow: Show[NonPrimaryFieldSchema] ): Show[VertexSchema] = vSchema => {
        // this will work, because otherwise `pShow` and `showPrimaryFieldSchema` will be same type implicits in one scope
        show"""VERTEX ${vSchema.vName} (${vSchema.pField}, ${vSchema.nPFields.map(np => show"np").mkString(", ")}) WITH primary_id_as_attribute="FALSE""""
    }
Scatie中提供的完整示例:

或者你也可以这样做:

implicit val showPrimaryFieldSchema: Show[PrimaryFieldSchema] = pf => {
    s"PRIMARY_ID ${pf.fName} ${pf.fType.show}"
}

implicit val showNonPrimaryFieldSchemaa: Show[NonPrimaryFieldSchema] = pf => {
    s"${pf.fName} ${pf.fType.show}"
}

implicit val showVertexSchema: Show[VertexSchema] = vSchema => {
  show"""VERTEX ${vSchema.vName} (${vSchema.pField}, ${vSchema.nPFields.map(np => show"np").mkString(", ")}) WITH primary_id_as_attribute="FALSE""""
}

在你复制错误之前,可能会一直玩这个Scastie,但请不要添加超出需要的内容。在这个页面上添加了更多细节更改你的scatie表并复制了它。你在那里做的是一个typeclass派生,这是一个与上下文传递不同的隐式用例(如
ExecutionContext
)或隐式转换因此,例如,您希望提供泛型类型的typeclass的实例(例如,
选项
),但为此,您需要证明泛型类型也有typeclass的实例。例如,
Option
的幺半群看起来像
implicit def optionMonoid[A](implicit aMonoid:Monoid[A]):幺半群[Option[A]]
。这就是您试图在此处复制的模式,但由于没有泛型值,但是一个具体的
PrimaryFieldSchema
然后隐式地请求它是没有意义的,并且创建了一个模棱两可的实例。看看你对
showFieldType
的定义,在那里你没有要求在调用
INT.show
时使用所有隐式,因为这些都是具体类型。我不明白你为什么要删除隐式?它定义了我认为的目的。@MaatDeamon我想向您说明编译错误的根本原因-它在一个作用域中存在冲突。我已经添加了您可以使用的替代方法。@MaatDeamon抱歉,没有冲突,但其含义不明确。请看下一篇文章,了解更多关于这个问题的细节:是的,这是真的,我也在考虑这个问题。因为事实上,我不知道在这个上下文中,参数中包含它会带来什么。。。。我需要考虑一下它的用法
// if you will remote implicit here 
val showPrimaryFieldSchema: Show[PrimaryFieldSchema] = pf => {
    s"PRIMARY_ID ${pf.fName} ${pf.fType.show}"
}

// and also here
val showNonPrimaryFieldSchemaa: Show[NonPrimaryFieldSchema] = pf => {
    s"${pf.fName} ${pf.fType.show}"
}

// Another working version
//implicit def showVertexSchema(implicit pShow: Show[PrimaryFieldSchema], npShow: Show[NonPrimaryFieldSchema] ): Show[VertexSchema] = vSchema => {
//    This works because you are using `pShow` explicetly, so no conflict.
//    s"""VERTEX ${vSchema.vName} (${pShow.show(vSchema.pField)}, ${vSchema.nPFields.map(np => npShow.show(np)).mkString(", ")}) WITH primary_id_as_attribute="FALSE""""
//}


implicit def showVertexSchema(implicit pShow: Show[PrimaryFieldSchema], npShow: Show[NonPrimaryFieldSchema] ): Show[VertexSchema] = vSchema => {
        // this will work, because otherwise `pShow` and `showPrimaryFieldSchema` will be same type implicits in one scope
        show"""VERTEX ${vSchema.vName} (${vSchema.pField}, ${vSchema.nPFields.map(np => show"np").mkString(", ")}) WITH primary_id_as_attribute="FALSE""""
    }
implicit val showPrimaryFieldSchema: Show[PrimaryFieldSchema] = pf => {
    s"PRIMARY_ID ${pf.fName} ${pf.fType.show}"
}

implicit val showNonPrimaryFieldSchemaa: Show[NonPrimaryFieldSchema] = pf => {
    s"${pf.fName} ${pf.fType.show}"
}

implicit val showVertexSchema: Show[VertexSchema] = vSchema => {
  show"""VERTEX ${vSchema.vName} (${vSchema.pField}, ${vSchema.nPFields.map(np => show"np").mkString(", ")}) WITH primary_id_as_attribute="FALSE""""
}