定义Scala特征的隐式视图

编程入门 行业动态 更新时间:2024-10-25 22:27:04
本文介绍了定义Scala特征的隐式视图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我正在做一个练习,在Scala中实现一个功能二叉搜索树,遵循我在Haskell中看到的类似模式。我有一个看起来像这样的结构: $ $ p $ $ $ $ $ b def遍历:Seq [A] ... } 案例类Branch [A](值:A,left:TreeNode [A],right:TreeNode [A])扩展TreeNode [A] { def isLeaf:Boolean = false def遍历:Seq [A] = ... ... } case class Leaf [A]()扩展TreeNode [A] { def isLeaf:Boolean = true def遍历:Seq [A] = Seq [A]() ... }

我会 em> 在 A 上放置一个类型约束,以便它只接受扩展 Ordered 的对象。看起来我需要在 Branch 和 Leaf ,以及 TreeNode trait ..我不能在 TreeNode trait中执行此操作,因为不接受视图边界。

据我所知, code><% -style view-bounds是隐式定义的语法糖,所以应该有一种写法在 TreeNode trait中手动定义绑定。不过,我不确定我应该怎么做。我已经环顾了一下,但还没有远远超过某种隐含的需求来定义。

任何人都可以指向正确的方向吗?我完全从错误的角度来看待这个问题吗?

解决方案

问题是视图边界以及上下文边界都只是语法糖用于特定类型的隐式参数。当应用于泛型类的类型参数(与应用于泛型方法相反)时,这些含义被添加到类的构造函数中。 由于特征没有构造函数(或者说,只有一个无参数构造函数),所以无处传递这些隐式参数,因此上下文边界和视图边界在通用特征上是非法的。 最简单的解决方案是将 TreeNode 变成一个抽象类。:

abstract class TreeNode [A<%Ordered [A]]

由Ben James建议,使用与 Ordering 绑定的上下文通常优于用 ORdered 绑定的视图更普遍)。但是问题仍然存在:不适用于特征。

如果将 TreeNode 转换为类是不实际的(比如你需要在类型层次结构中的不同位置混合使用),你可以在 TreeNode 中定义一个抽象方法来提供隐式值(类型 Ordered [A] )并让所有扩展它的类定义它。这不幸的是更详细和明确,但你不能在这种情况下做得更好:

trait TreeNode [A] { implicit protected def toOrdered:A => Ordered [A]](value:A,left:TreeNode [A],right:TreeNode [A])extends TreeNode [A] } case class Branch [A& [A] { protected def toOrdered =隐式[A =>有序[A]] } 案例类叶[A <%Ordered [A]]()扩展TreeNode [A] {保护def toOrdered =隐式[A = >已订购[A]] }

I'm doing an exercise to implement a functional binary-search-tree in Scala, following a similar pattern that I've seen used in Haskell. I have a structure that looks something like this:

trait TreeNode[A] { def isLeaf: Boolean def traverse: Seq[A] ... } case class Branch[A](value: A, left: TreeNode[A], right: TreeNode[A]) extends TreeNode[A] { def isLeaf: Boolean = false def traverse: Seq[A] = ... ... } case class Leaf[A]() extends TreeNode[A] { def isLeaf: Boolean = true def traverse: Seq[A] = Seq[A]() ... }

I'd like to put a type constraint on A so that it will only accept objects that extend Ordered. It looks like I need to define a view bound on A ([A <% Ordered[A]]) on Branch and Leaf, as well as the TreeNode trait.. I can't do this on the TreeNode trait, however, because view bounds aren't accepted.

As I understand, <%-style view-bounds are syntactic sugar for an implicit definition, so there should be a way to write to define the bound manually within the TreeNode trait. I'm not sure how I'm supposed to do this, though. I've looked around a bit, but haven't gotten much further than that some sort of implicit needs to be defined.

Can anybody point me in the right direction? Am I approaching this from the wrong angle entirely?

解决方案

The problem is that view bounds as well as context bounds are just syntactic sugar for specific types of implicit parameters. When applied to a type parameter of a generic class (as opposed to when applied to a generic method), these implicits are added to the constructor of the class. Because traits have no constructor (or rather, only have a single parameterless constructor), there is nowhere to pass these implicit parameters and thus context bounds and view bounds are illegal on generic traits. The simplest solution would be to turn TreeNode into an abstract class.:

abstract class TreeNode[A <% Ordered[A]]

Note that as advised by Ben James, using a context bound with an Ordering is usually better than a view bound with an ORdered (it is more genral). However the problem is still the same: won't work on a trait.

If turning TreeNode into a class is not practical (say you need to mix it at various places in the type hierarchy), you can define an abstract method in TreeNode that will provide the implicit value (of type Ordered[A]) and have all the classes that extend it define it. This unfortunately more verbose and explicit, but you can't do much better in this case:

trait TreeNode[A] { implicit protected def toOrdered: A => Ordered[A] } case class Branch[A<%Ordered[A]](value: A, left: TreeNode[A], right: TreeNode[A]) extends TreeNode[A] { protected def toOrdered = implicitly[A => Ordered[A]] } case class Leaf[A<%Ordered[A]]() extends TreeNode[A] { protected def toOrdered = implicitly[A => Ordered[A]] }

更多推荐

定义Scala特征的隐式视图

本文发布于:2023-11-10 22:50:24,感谢您对本站的认可!
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:视图   特征   定义   隐式   Scala

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!