将自定义类型从F#转换为Scala

时间:2016-09-09 14:45:30

标签: scala f#

我开始学习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#语法?

1 个答案:

答案 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一起使用。请注意,这不会处理mapflatMap问题。