我具有以下用于解析的特征,这些特征为对象的开头和结尾提供文件位置:
case class FilePosn(lineNum :Int, tabs: Int, spaces: Int, fileName: String)
{/*code omitted*/}
trait PosnEnds
{
def startPosn: FilePosn
def endPosn: FilePosn
def multiLine: Boolean = startPosn.lineNum != endPosn.lineNum
def OneLine: Boolean = startPosn.lineNum == endPosn.lineNum
def indent: Int = startPosn.tabs
def startLine: Int = startPosn.lineNum
def endLine: Int = endPosn.lineNum
}
object FilePosnVoid extends FilePosn(0, 0, 0, "There is no File position")
{ override def posnString(indentSize: Int): String = "No File Posn: " }
在伴生对象中,我创建了一个隐式的,因此 PosnEnds 序列本身就是隐式 PosnEnds:
object PosnEnds
{
implicit class ImpPosnEndsSeq[A <: PosnEnds](thisSeq: Seq[A]) extends PosnEnds
{
override def startPosn: FilePosn = thisSeq.fHead(FilePosnVoid, (h, t) => h.startPosn)
override def endPosn: FilePosn = thisSeq.fLast(FilePosnVoid, _.endPosn)
}
}
无论如何要递归使用隐式,因此 Seq[Seq[A]] 和 Seq[Seq[Seq[A]]] 等将被隐式转换为 PosnEnds 特征?在实践中,我可能不需要很大的深度,但最好使用一个优雅的解决方案,隐式转换任意深度的 Seq。
目前对于深度 2,我正在使用:
implicit class ImpPosnEndsSeqSeq[A <: PosnEnds](thisSeq: Seq[Seq[A]]) extends PosnEnds
{
override def startPosn: FilePosn = thisSeq.fHead(FilePosnVoid, (h, t) => h.startPosn)
override def endPosn: FilePosn = thisSeq.fLast(FilePosnVoid, _.endPosn)
}