[英]DSL Like Syntax in Scala
我正在嘗試提出一個可以這樣調用的CSV分析器:
parser parse "/path/to/csv/file" using parserConfiguration
解析器將是一個包含目標案例類的類,CSV文件將被解析為該案例類:
class CSVParser[A] {
def parse(path: String) = Source.fromFile(fromFilePath).getLines().mkString("\n")
def using(cfg: ParserConfig) = ??? How do I chain this optionally???
}
val parser = CSVParser[SomeCaseClass]
我設法站起來,可以打電話給我:
parser parse "/the/path/to/the/csv/file/"
但是我還不想運行parse方法,因為我想使用上述提到的DSL之類的配置來應用配置! 因此,這里有兩個規則。 如果調用者不提供parserConfig,則我應該能夠使用默認值運行,但是如果用戶提供parserConfig,則我想應用配置,然后運行parse方法。 我嘗試使用隱式組合,但無法使其正常工作!
有什么建議么?
編輯:所以解決方案看起來像這樣,根據“ Cyrille Corpet”的評論:
class CSVReader[A] {
def parse(path: String) = ReaderWithFile[A](path)
case class ReaderWithFile[A](path: String) {
def using(cfg: CSVParserConfig): Seq[A] = {
val lines = Source.fromFile(path).getLines().mkString("\n")
println(lines)
println(cfg)
null
}
}
object ReaderWithFile {
implicit def parser2parsed[A](parser: ReaderWithFile[A]): Seq[A] = parser.using(defaultParserCfg)
}
}
object CSVReader extends App {
def parser[A] = new CSVReader[A]
val sss: Seq[A] = parser parse "/csv-parser/test.csv" // assign this to a val so that the implicit conversion gets applied!! Very important to note!
}
我想我需要在調用解析器解析的位置獲取作用域中的隱式對象,但是與此同時,我不想弄亂上面的結構!
如果using
優先級高於parse
的運算符代替using
,則無需額外的類型注釋就可以使其起作用。 以<<
為例
object parsedsl {
class ParserConfig
object ParserConfig {
val default = new ParserConfig
}
case class ParseUnit(path: String, config: ParserConfig)
object ParseUnit {
implicit def path2PU(path: String) = ParseUnit(path, ParserConfig.default)
}
implicit class ConfigSyntax(path: String) {
def <<(config: ParserConfig) = ParseUnit(path, config)
}
class CSVParser {
def parse(pu: ParseUnit) = "parsing"
}
}
import parsedsl._
val parser = new CSVParser
parser parse "path" << ParserConfig.default
parser parse "path"
您的parse
方法應該只給出部分結果,而不做任何事情。 要處理默認的implem,可以使用隱式轉換來輸出類型:
class CSVParser[A] {
def parse(path: String) = ParserWithFile[A](path)
}
case class ParserWithFile[A](path: String) {
def using(cfg: ParserConfig): A = ???
}
object ParserWithFile {
implicit def parser2parsed[A](parser: ParserWithFile[A]): A = parser.using(ParserConfig.default)
}
val parser = CSVParser[SomeCaseClass]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.