2017-04-04 66 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()) 
}