Home > Blockchain >  Is there a reason we can define a type alias for a value literal?
Is there a reason we can define a type alias for a value literal?

Time:11-15

Type aliases might typically be used like this:

type Point = (Double, Double)

but I was playing with the scala repl and you could do this as well:

type Two = 2

with this alias you can define the function:

scala> def three(x: Two) = x   1
def three(x: Two): Int

scala> three(1)
-- Error:
1 |three(1)
  |      ^
  |      Found:    (1 : Int)
  |      Required: Two

scala> three(2)
val res0: Int = 3

As you can see Two really does seem to represent the singleton type of 2. It only seems to work with value literals, not variables:

scala> val x = 2
val x: Int = 2

scala> type Two = x
-- Error:
1 |type Two = x
  |           ^
  |           Not found: type x

Also it seems to work with some function values but not others:

scala> type AlwaysThree = () => 3
// defined alias type AlwaysThree = () => 3

scala> type AlwaysThree = () => 2   1
-- Error:
1 |type AlwaysThree = () => 2   1
  |                           ^
  |                           Not found: type  

I'm wondering why scala allows this. Is there a reason this little thing is here?

CodePudding user response:

Yes, you can define type aliases for any types, and 2 is a perfectly valid type. Specifically, it's the type which contains only the number 2 and nothing else.

type AlwaysThree = () => 3

A function takes arguments and has a return type. This is the function type which takes no arguments and unconditionally returns the number 3. An example function of this type might be () => 3.

type AlwaysThree = () => 2   1

This is attempting to use an infix type alias. It's more like

type AlwaysThree = () => Foo[1, 2]

where instead of the type Foo, we have . You could very easily define a type called

type  [A, B] = A

and then 1 2 would be valid as a type. Though getting the type A B to represent the numerical value of A plus that of B may be a bit trickier. I'll leave that as an exercise to the reader.

CodePudding user response:

To complete @Silvio's answer, a great use case for these types is union types to define a very precise set of values a method can return or accept.

For instance:

type LastDay = 28 | 29 | 30 | 31

def getLastDayOfMonth(month: String): LastDay = ???

Or:

type Role = "Driver" | "Passenger"

def getInTheCar(role: Role) = ???
  • Related