Created
September 26, 2015 18:23
-
-
Save ceylonwebide/b49ba50c98c1b288af20 to your computer and use it in GitHub Desktop.
EXAMPLE: Type parameters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//$webrun_wrapped | |
shared void run() { | |
// Ceylon allows generic types and functions, i.e. they may have | |
// type parameters: | |
class Generic<Item>(item) { | |
shared variable Item item; | |
shared Item f(Item other) => other; | |
} | |
Item genericFunc<Item>(Item i) => i; | |
// Note that a Generic<String> is not a Generic<Object>: | |
// Generic<Object> obj = Generic<String>("test"); | |
// obj.item := 5; //ouch! | |
// But for some types such a relation is possible, namely if the | |
// generic type is only used as return type, not for method | |
// parameters: | |
class Covariant<out Item>(item) { | |
shared Item item; | |
shared Item? f() => null; | |
} | |
Covariant<Object> obj = Covariant<String>("test"); | |
Object i1 = obj.item; // No conflict arises if Item is only | |
Object? i2 = obj.f(); // used as return type. | |
// We have to mark such a type parameter "out" (see above). | |
// The exact opposite is also possible: | |
class Contravariant<in Item>(Item i) { | |
shared void f(Item i) { /*...*/ } | |
} | |
Contravariant<String> obj2 = Contravariant<Object>("test"); | |
obj2.f("hi"); // no conflict, a String is an Object | |
// We can specify bounds for the type parameter: | |
class Tools<out Num>(Num x, Num y) | |
given Num satisfies Number<Num> { | |
// We know that x and y are numbers (type Number<Num>), | |
// so we can use the corresponding operations/methods. | |
shared Num dist() => (x < y) then (y-x) else (x-y); | |
} | |
Tools<Float> t1 = Tools<Float>(-3.1, 0.62); | |
print("t1.dist() = ``t1.dist()``"); | |
// Let the compiler infer the types: | |
value t2 = Tools(814, 5); | |
print("t2.dist() = ``t2.dist()`` (type ``className(t2.dist())``)"); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment