2017-04-04 68 views
0

我想写一个API,让我能够轻松地创建像类型安全的阶层式结构

/ foo/bar/baz 

对于这种分级密钥我创建了以下类:

sealed trait Key { 
    def path: String 

    def /(key: String): Node = Node(this, key) 
} 

case object Root extends Key { 
    override def path: String = "" 
} 

final case class Node(parent: Key, key: String) extends Key { 
    override def path: String = s"${parent.path}/$key" 
} 

和它的作品完美的罚款:现在

Root/"foo"/"bar" 

,我也希望能够包括“占位符”,像这样:

Root/"foo"/% 

然后这应返回的东西,当一个字符串被应用于回报更换Key对象与给定值,即

(Root/"foo"/%)("bar") == Root/"foo"/"bar" 

请记住,这应该在正水平工作,像这样:

Root/%/"foo"/%/"bar" 
+0

会是什么'(根/%/“富“/%/”bar“)(”baz“)'是? –

回答

2

这可能不是很有效,但它做你的要求。

需要注意的是,回答我的评论,我决定

(Root/%/"foo"/%/"bar")("baz") == (Root/%/"foo"/"baz"/"bar") 

,但没有太多的改变有不同的结果。

object % // only for nicer API 

trait Slashable[T <: Slashable[T]] { 
    def /(key: String): T 
    def /(p: %.type): PlaceHeld[T] = PlaceHeld[T](str => /(str)) 
} 

case object Root extends Key { 
    override def path: String = "" 
} 

sealed trait Key extends Slashable[Key] { 
    def path: String 

    def /(key: String): Node = Node(this, key) 
} 


final case class Node(parent: Key, key: String) extends Key { 
    override def path: String = s"${parent.path}/$key" 
} 

case class PlaceHeld[T <: Slashable[T]](replace: String => T) extends Slashable[PlaceHeld[T]]{ 
    def /(key: String) = PlaceHeld(str => replace(str)./(key)) 
    def apply(key: String) = replace(key) 
} 

编辑

你可能想通过一个简单的(包裹)Seq更换你的基地型(无占位符):

case class Key(pathSeq: Seq[String]) extends Slashable[Key] { 
    def path = pathSeq.mkString("/") 
    def /(key: String) = Key(pathSeq :+ key) 
} 

object Root extends Slashable[Root] { 
    def path = ""      //this is because we cannot do 
    def /(key: String) = Key(Seq(key)) //Root extends Key(Seq()) 
}