Unsafe Type and Effect Casts
Flix supports both type and effects casts but they should be used with extreme care.
A better solution is to use a compiler-checked supercast or effect upcast (if possible).
Type Casts
A type cast instructs the compiler that an expression has a specific type.
Warning️️: Type casts are very dangerous and should be used with utmost caution!
A Flix programmer should, under normal circumstances, never need to use a type cast.
Example: Safe Cast to a Super-Type
The expression below casts a String
to an Object
:
unsafe_cast "Hello World" as ##java.lang.Object
(Note: It is safer to use the supercast
expression.)
Example: Safe Cast from Null to an Object-Type
The expression below casts the null
value (of type Null
) to String
:
unsafe_cast null as ##java.lang.String
(Note: It is safer to use the supercast
expression.)
Example: Unsafe Cast
The expression below contains an illegal cast and triggers a ClassCastException
:
unsafe_cast (123, 456) as ##java.lang.Integer
Primitive Values and Boxing
A type cast should not be used to box or unbox primitive values. Instead use
the designated Java methods. For example, Integer.valueOf
and
Integer.intValue
.
Effect Casts
An effect cast instructs the compiler that an expression has a specific effect.
Warning️️: Effect casts are extremely dangerous and should be used with extreme caution!
A Flix programmer should, under normal circumstances, never need to use an
effect cast. In a few rare cases, which involve sub-effecting, an effect cast
may be necessary. Most of these cases can be handled by the safer upcast
expression.
Example: Safe Cast of Pure Function to Effect Polymorphic
Flix does not (yet) have sub-effecting which means that in certain rare cases it can be necessary to manually insert a cast. For example:
def findRight(f: a -> Bool \ ef, l: List[a]): Option[a] \ ef =
def loop(ll, k) = match ll {
case Nil => k()
case x :: xs => loop(xs, () -> if (f(x)) Some(x) else k())
};
loop(l, () -> (unsafe_cast None as _ \ ef))
Here the cast unsafe_cast None as _ \ ef
is required because otherwise the
function () -> None
would be pure and not effect polymorphic as required.
Warning: Never cast effectful expressions to pure. You have been warned.