Suppose I have a few functions
val f1: Int => Error1 \/ Int = ??? // maybe should use Kleisli instead
val f2: Int => Error2 \/ Int = ???
val f3: Int => Error3 \/ Int = ???
... and I need to compose them:
val f123 = {a: Int =>
for(b <- f1(a); c <- f2(b); d <- f3(c)) yield d // does not compile
}
f123
should return Error1 | Error2 | Error3 \/ Int
but I don't have |
in Scala and hence I am using inheritance:
sealed trait Error123
object Error1 extends Error123
object Error2 extends Error123
object Error3 extends Error123
val f123: Int => Error123 \/ Int = ... // now it compiles
... but what if I need to compose f1
and f2
?
Should I create a new trait Error12
and make Error1
and Error2
extend it ? What if I have five functions f1
, f2
, ..., f4
, f5
and five error classes ?
I don't like this inheritance approach because it changes already existing types Error1
, Error2
et al just to define their unions. So I am wondering how to unionize these types in Scala.
As the name suggests, a Union Type denotes a type that is the union of two or more types. For example, we can define a union type of Int and String values and use it as a parameter of a function that expects either an integer or string value as input. Scala is a strongly and statically typed language.
Type declaration is a Scala feature that enables us to declare our own types. In this short tutorial, we'll learn how to do type declaration in Scala using the type keyword. First, we'll learn to use it as a type alias. Then, we'll learn to declare an abstract type member and implement it.
In TypeScript, a union type variable is a variable which can store multiple type of values (i.e. number, string etc). A union type allows us to define a variable with multiple types. The union type variables are defined using the pipe ( '|' ) symbol between the types. The union types help in some special situations.
A type class is an abstract, parameterized type that lets you add new behavior to any closed data type without using sub-typing. If you are coming from Java, you can think of type classes as something like java.
IMHO, this is the best approach. What are you trying to do? Define a function that may return either a result or an error of type Error123
, what else it there to say?
By defining Error123
as a sealed trait and extending it with N case classes better describing the error you make sure that the caller will have to handle all cases since the compiler will ask him to use an exhaustive pattern matching.
If it is that verbose and cumbersome maybe you need to rethink the ADT of your error cases.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With