Есть ли какой-нибудь способ в Scala иметь "специальные" ADT? - PullRequest
0 голосов
/ 07 июля 2019

Я хочу полностью избавиться от исключений в моем коде Scala, вместо этого возвращать явные / типизированные результаты (ADT) из методов, подобных этому:

class SomeService {

  def method1: Method1Result = ...
}

object SomeService {

  trait Method1Result
  object Method1Result {
    case class Success(id: String) extends Method1Result
    case object AlreadyExists  extends Method1Result
    case object Error extends Method1Result
  }
}

Но, как вы видите, это слишком шаблонно ....

В идеале я хотел бы иметь что-то вроде этого:

class SomeService {
  def method1: Success(id: String) | AlreadyExists | Error
}

Итак, как вы видите, ADT определен в типе возврата method1

* 1011.* Может быть, есть некоторые плагины компилятора или библиотеки обработки аннотаций, которые позволяют писать такой код и генерировать ADT под капотом?

Или как лучше всего использовать Scala, если я хочу вернуть типизированные результаты из метода?

Ответы [ 2 ]

3 голосов
/ 07 июля 2019

Вы можете использовать Coproduct из shapeless.Не уверен, имеет ли смысл идти по этому пути в коде уровня приложения.

import shapeless.{:+:, CNil, Coproduct}

case class Success(id: String)
case class AlreadyExists
case class Error
type AllThree = Success :+: AlreadyExists :+: Error :+: CNil

Или вы можете создать себе такие типы, как Either3[A, B, C], Either4[A,B,C,D], ... и решить их с некоторым количествомшаблонный.

2 голосов
/ 07 июля 2019

Scala 3 может принести типов объединений , где мы сможем написать именно это.Вы можете попробовать это в Scastie , выбрав цель компилятора Dotty.

Например https://scastie.scala -lang.org / 19tnxxxyTua2utD6QCocaw

object Main extends App {  
  case class Success(id: String)
  case object AlreadyExists
  case object Error

  def method1: Success | AlreadyExists.type | Error.type = AlreadyExists

  println(method1)
}

который выводит

AlreadyExists
...