隐式和召唤有啥区别?

Posted

技术标签:

【中文标题】隐式和召唤有啥区别?【英文标题】:What's the difference between implicitly and summon?隐式和召唤有什么区别? 【发布时间】:2021-09-23 00:12:32 【问题描述】:

在 Scala 3 中 summon 似乎与旧的 implicitly 做同样的事情。但是,当我们深入研究实际示例时,我们发现情况并非如此。例如

case class A(i: Int, s: String)

val mirror    = implicitly[Mirror.Of[A]]    
type ValueOfs = Tuple.Map[mirror.MirroredElemLabels, ValueOf]
val valueOfs  = summonAll[ValueOfs]

def values(t: Tuple): Tuple = t match
  case (h: ValueOf[_]) *: t1 => h.value *: values(t1)
  case EmptyTuple => EmptyTuple

产生错误

cannot reduce inline match with  
 scrutinee:  compiletime.erasedValue[App.ValueOfs] : App.ValueOfs  
 patterns :  case _:EmptyTuple  
             case _:*:[t @ _, ts @ _]

但是用summon[Mirror.Of[A]] 替换implicitly[Mirror.Of[A]] 编译正常。

在这种情况下和一般情况下,summonimplicitly 的微妙之处是什么?

【问题讨论】:

This answer 可能是相关的。虽然我对 Scala 3 的 Mirror 类型了解不多,无法将其与您的代码 sn-p 连贯地联系起来,所以我会让其他人来做这个荣誉。 summon 类似于shapeless.the typelevel.org/blog/2014/01/18/implicitly_existential.html ***.com/questions/65634897/… ***.com/questions/65062041/… ***.com/questions/64438704/… 【参考方案1】:

给定

case class A(i: Int, s: String)

我们可以看到summonimplicitly 返回相同的运行时值

assert(implicitly[Mirror.Of[A]] eq summon[Mirror.Of[A]])

但它们有不同的编译时间类型

def fun[A,B]( a: A, b: B )( implicit ev: A =:= B ) = ???
fun(implicitly[Mirror.Of[A]], summon[Mirror.Of[A]])
    Cannot prove that deriving.Mirror.Of[Worksheet.A] =:= (
      deriving.Mirror
        MirroredType = Worksheet.A; MirroredMonoType = Worksheet.A; 
          MirroredElemTypes <: Tuple
      
     & 
      scala.deriving.Mirror.Product
        MirroredMonoType = Worksheet.A; MirroredType = Worksheet.A; 
          MirroredLabel = ("A" : String)
      
    )
      MirroredElemTypes = (Int, String); 
        MirroredElemLabels = (("i" : String), ("s" : String))
    .

summon 返回的更具体,尽管我不确定这如何/为什么适用于问题中的情况。

【讨论】:

以上是关于隐式和召唤有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章

C#接口的隐式和显式实现之间的区别[重复]

端口为开漏式和推免式的硬件电路设计有啥区别,

英语中的Resize和Resized有啥区别?

关于隐式转换和显式转换

“布尔”和“布尔”有啥区别?

Authorization code grant 和 Implicit grant 有啥区别