Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Shapeless Witness and how it can give the actual singleton type

I'm trying to understand singleton types in shapeless and faced misunderstanding about singleton types compile-time type. Here is an example:

val x: Witness.`120`.T = 120.narrow

It works fine, but this constructions looks very unusual. What is Witness.120? In IDE it points to some macro function selectDynamic:

def selectDynamic(tpeSelector: String): Any = macro SingletonTypeMacros.witnessTypeImpl

which has compile-time type Any and judging by the construction Witness.120.T a type member T. This looks like magic... Can anyone give some explanation on what actually is going on when one writes something like:

val x: Witness.`120`.T = //...
like image 460
Some Name Avatar asked Dec 16 '19 10:12

Some Name


1 Answers

Witness creates a so-called literal-based singleton type. Literal type means it's a type that can only accept one value.

So if you create a function like this:

def f(x: Witness.`120`.T) = x

it would accept only integer 120, but not 121.

Since Scala 2.13 literal types are integrated into the language, so you can write it simply as:

def f(x: 120) = x

Function narrow narrows type of value 120 from general Int to literal 120.

like image 192
Krzysztof Atłasik Avatar answered Oct 17 '22 10:10

Krzysztof Atłasik