簡體   English   中英

了解Scala Implicits

[英]Understanding Scala Implicits

在閱讀Chiusano和Bjarnason的Scala函數式編程時 ,我在第9章Parser Combinators中遇到了以下代碼:

trait Parsers[ParseError, Parser[+_]] { self =>
  ...
  def or[A](s1: Parser[A], s2: Parser[A]): Parser[A]
  implicit def string(s: String): Parser[String]
  implicit def operators[A](p: Parser[A]) = ParserOps[A](p)
  implicit def asStringParser[A](a: A)(implicit f: A => Parser[String]):
    ParserOps[String] = ParserOps(f(a))

  case class ParserOps[A](p: Parser[A]) {
    def |[B>:A](p2: Parser[B]): Parser[B] = self.or(p,p2)
    def or[B>:A](p2: => Parser[B]): Parser[B] = self.or(p,p2)
  }
}

我理解,如果在編譯期間存在類型不兼容或缺少參數,Scala編譯器將查找缺少的函數,該函數將非匹配類型轉換為所需類型或范圍內的變量,分別具有適合缺失參數的所需類型。

如果字符串出現在需要Parser[String] ,則應調用上述特征中的字符串函數將字符串轉換為Parser[String]

但是,我很難理解operatorsasStringParser函數。 這些是我的問題:

  1. 對於隱式運算符函數,為什么不存在返回類型?
  2. 為什么ParserOps定義為一個case class ,為什么不能| 或者在Parsers特征本身中定義or函數?
  3. asStringParser想要完成什么? 它的目的是什么?
  4. 為什么需要self 這本書說,“使用self來明確消除對特征或方法的引用的歧義”,但這是什么意思?

我真的很喜歡這本書,但本章中使用高級語言特定的結構阻礙了我的進步。 如果你能向我解釋這段代碼是如何工作的,那將會很有幫助。 據我所知,目標是讓庫“更好”通過像|運營商使用 or ,但不明白這是怎么做的。

  1. 每個方法都有一個返回類型。 在這種情況下,它是ParserOps[A] 您不必明確地將其寫出來,因為在這種情況下可以自動推斷出來。
  2. 可能是因為伴隨對象中自動提供的ParserOps.apply -factory方法。 在構造函數中需要更少的val ,並且您不需要new關鍵字來實例化ParserOps 雖然它不用於模式匹配,所以,你可以用普通(非case )類做同樣的事情,無關緊要。
  3. 這是“pimp-my-library” - 模式。 它附加方法| 和/ or Parser ,沒有強迫Parser繼承任何東西。 通過這種方式,您可以稍后聲明Parser是像ParserState => Result[A]但你仍然有方法| 和/ or可用(即使Function1[ParserState, Result[A]]沒有它們)。
  4. 你可以把| or直接在Parsers ,但是你必須使用語法

     |(a, b) or(a, b) 

    而不是更好

     a | b a or b 

Scala中沒有“真正的運算符”,一切都是方法。 如果您想要實現一個行為就像它是一個中綴運算符的方法,那么您可以完成本書中的操作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM