【问题标题】: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 的微妙之处是什么?

【问题讨论】:

标签: scala implicit scala-3


【解决方案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 返回的更具体,尽管我不确定这如何/为什么适用于问题中的情况。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-04
    • 1970-01-01
    • 1970-01-01
    • 2011-03-04
    • 2018-09-05
    • 1970-01-01
    相关资源
    最近更新 更多