我开始学习Scala的兴趣,我决定将Scott Wlaschin的parser combinators软件包从F#翻译成Scala,所以这些东西真的会解决。 斯科特的一揽子方案的全部意义在于几乎无处不在地使用monad,所以我也认为这是一个了解monad的机会。
在其中一张早期幻灯片中,他定义了类型type Parser<'a> = Parser of (string -> Result<'a * string>)
,其中:
type Result<'a> =
| Success of 'a
| Failure of string
这个定义中的微妙之处在于'a
等式两边的Parser<'a>
之间的耦合。
无论如何,我如何将上述陈述翻译成Scala,同时保留我提到的微妙之处?
对于第一个我想到的:
type ParserType[T] = String => Result[(T, String)]
和第二个(这是一个选择类型)我想到了这个:
sealed trait Result[T]
case class Success[T](result: T) extends Result[T]
case class Failure[T](msg: String) extends Result[T]
但是,在[T]
中使用Failure
似乎很愚蠢,因为它根本不使用T
。是否有一些语法可以更接近F#语法?
答案 0 :(得分:5)
在Scala 2.12中查看新的右侧偏向Either
(禁止在Cats lib中有一个Xor
数据类型。)但是,直接回答您的问题:
sealed trait Result[+T]
case class Success[T](result: T) extends Result[T]
case class Failure(msg: String) extends Result[Nothing]
这利用了类型协方差。此处的任何Failure
都可以与任何Success
一起使用。请注意,这不会处理map
或flatMap
问题。