使用Scala隐式的类型平等
我一直在阅读一些
Scala类型编程的东西.主要是Apocalisp博客,也是Alexander Lehmann的YouTube谈话.
我有点困惑我猜这可能是非常基本的,这是使用隐含的比较两种类型,如下所示: implicitly[Int =:= Int] Apocalisp博客上的标记说:
我得到如何使这项工作,但我不知道为什么它的工作,所以不想继续前进. 在上面的例子中有一个隐含的类型“Int”在范围内,“隐含地”从以太网中获取,允许代码编译?如何与’function1’返回类型相符? res0: =:=[Int,Int] = <function1> 此外,这隐含于哪里?在我的特质“Foo”的情况下,为什么呢? implicitly[Foo =:= Foo] 编译?在这种情况下,“Foo”隐含在哪里? 如果这是一个非常愚蠢的问题,提前道歉,谢谢任何帮助! 解决方法
X =:= Y只是类型= = = [X,Y]的句法糖(中缀符号).
所以当你隐含地[Y =:= Y]时,你只需要查找一个类型为= = = [X,Y]的隐式值. 另外,=:=是一个有效的类型名称,因为类型名称(就像任何标识符)可以包含特殊字符. 从现在开始,我们将= = =重新命名为IsSameType,并删除中缀符号,以使我们的代码更加清晰直观. 以下是这种类型定义的简化版本: sealed abstract class IsSameType[X,Y] object IsSameType { implicit def tpEquals[A] = new IsSameType[A,A]{} } 注意tpEquals如何为任何类型A提供IsSameType [A,A]的隐式值. 所以使用这个非常简单的结构,我们可以静态地检查一些类型X与另一个类型Y相同. 现在这里是一个如何有用的例子.说我想定义一个Pair类型(忽略它已经存在于标准库中的事实): case class Pair[X,Y]( x: X,y: Y ) { def swap: Pair[Y,X] = Pair( y,x ) } Pair参数化与其2个元素的类型,这可以是任何东西,最重要的是不相关. case class Pair[X,x ) def toList( implicit evidence: IsSameType[X,Y] ): List[Y] = ??? } 但是实际上实现toList还是一个严重的问题.如果我尝试编写明显的实现,则无法编译: def toList( implicit evidence: IsSameType[X,Y] ): List[Y] = List[Y]( x,y ) 编译器会抱怨x不是Y类型.实际上,就编译器来说,X和Y仍然是不同的类型. 如果我们知道X == Y(或换句话说,我们在范围内有一个IsSameType [X,Y]的一个实例),我们可以做的是提供从X到Y的隐式转换. // A simple cast will do,given that we statically know that X == Y implicit def sameTypeConvert[X,Y]( x: X )( implicit evidence: IsSameType[X,Y] ): Y = x.asInstanceOf[Y] 现在,我们对toList的实现最终编译成精细:x将通过隐式转换sameTypeConvert简单地转换为Y. 作为最后的调整,我们可以进一步简化事情:鉴于我们已经将隐含的价值(证据)作为参数, sealed abstract class IsSameType[X,Y] extends (X => Y) { def apply( x: X ): Y = x.asInstanceOf[Y] } object IsSameType { implicit def tpEquals[A] = new IsSameType[A,A]{} } 然后,我们可以删除sameTypeConvert方法,因为IsSameType实例本身现在提供了隐式转换. 我们现在基本上重新实现了Predef中定义的类型=:= (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |