Enumeration subtype element as parameter in Scala - scala

I have a generic class for which the type must be a subtype of Enumeration
class MyClass[A<: Enumeration](val parameter1 : Int,
val parameter2: A) {
}
Inside this class, there is a method that needs to take an element from the enum A as parameter. I cannot find the proper way to write the signature of the method.
def myMethod(element: A.Values): Resource2[A] = {
this
}
Intellisense says
Cannot resolve symbol A
How can I write the method so it takes an element of the enum A ?

The type is Value (not Values) and, because A is a type and not an instance (i.e. not a value), the syntax for referencing a type within a type is element: A#Value.

Related

How to check if a type is a subtype of another in dart

I've recently found myself in a situation where I wanted to check if a Type is a subtype of another Type this is what I've tried
abstract class Record{}
class TimeRecord extends Record{}
void test(){
print(TimeRecord is Record); // return false but why ??
}
The only time it makes sense to check if one type is a subtype of another type is when at least one of the types is a type variable. (Otherwise, you can just look at the source and write a constant true or false into the code).
There is a way to check whether one type is a subtype of another, and it does use the is operator, but you need to have an instance as the first operand and a type as the second. You can't just create an instance of an unknown type, so we instead rely in Dart's covariant generics:
bool isSubtype<S, T>() => <S>[] is List<T>;
(You can use any generic class, or even create your own, instead of using List. All it needs is a way to create the object.)
Then you can write:
print(isSubtype<TimeRecord, Record>()); // true!
The is keyword is used to check if an object instance is an object of type T, and not if a type is another type:
abstract class Record{}
class TimeRecord extends Record{}
void test(){
print(TimeRecord() is Record); // returns true!
}
Just to add up to #lrn answer.
You could also do something like:
extension NullableObjectsExtensions<T> on T {
bool isSubtypeOf<S>() => <T>[] is List<S>;
bool isSupertypeOf<S>() => <S>[] is List<T>;
}
So this way you can test any variable anywhere.

Using type as a value, why is the "self" keyword required here?

I'm currently learning type as a value in functions and wrote this sample code to play around:
import Foundation
class Animal {
func sound() {
print("Generic animal noises")
}
}
func foo(_ t:Animal) {
print("Hi")
}
foo(Animal) //Cannot convert value of type 'Animal.Type' to expected argument type 'Animal'
I'm not surprised by this result. Obviously you cant pass the type itself as an argument where an instance of that type is expected. But notice that the compiler says that the argument I passed was of type Animal.Type. So if I did this, it should compile right?
func foo(_ t:Animal.Type) {
print("Hi")
}
foo(Animal) //Expected member name or constructor call after type name
This is what really confuses me a heck ton, the compiler told me it was of type Animal.Type *but after making this change it once again shows an error.
Of course I listened to the fix Swift suggests and do:
foo(Animal.self) //Works correctly
But my biggest question is: WHY? Isn't Animal itself the type? Why does the compiler require me to use Animal.self to get the type? This really confuses me, I would like for some guidance.
Self-answering, with help of comments, I was able to find out the reason:
Using .self after the type name is called Postfix Self Expression:
A postfix self expression consists of an expression or the name of a
type, immediately followed by .self. It has the following forms:
expression.self
type.self
The first form evaluates to the value of the expression. For example, x.self evaluates to x.
The second form evaluates to the value of the type. Use this form to access a type as a value. For example, because SomeClass.self evaluates to the SomeClass type itself, you can pass it to a function or method that accepts a type-level argument.
Thus, the .self keyword is required to consider the type as a value capable of being passed as an argument to functions.

What exactly is a metatype in Swift?

I am very confused around the concept of "metatype" in the Swift language.
Suppose I have:
class SomeClass {
class func callClassMethod() {
print("I'm a class method. I belong to my type.")
}
func callInstanceMethod() {
print("I'm an instance method. I belong to my type instance.")
}
}
According to the definition:
A metatype type refers to the type of any type, including class types,
structure types, enumeration types, and protocol types.
SomeClass is already a type called SomeClass, then what exactly is the type of SomeClass?
I can create a SomeClass.Type variable:
let var1 : SomeClass.Type = SomeClass.self
var1.doIt();//"I'm a class method. I belong to my type."
but I can also call the static/class function this way:
SomeClass.doIt();//"I'm a class method. I belong to my type."
Are they the same?
They are the same because the compiler guarantees that class names are unique (Swift is name spaced by module), so there is only one thing that is of SomeClass.Type and that is the class SomeClass. The meta type is often useful when you just want to pass the type of something to a function but you don't want to pass an instance. Codable does this for instance:
let decoded = try decoder.decode(SomeType.self, from: data)
If you could not pass the meta type here then the compiler could still infer the return type based on an annotation on the left, but it would be less readable:
let decoded: Sometype = try decoder.decode(data)
Some libraries do use the type inference style instead, although the Apple preference seems to be to use the meta type as its clearer what the right side of the assignment is on its own, without relying on type inference from the left side of the assignment.

Swift grammar explicit member expression

In the grammar section of the Swift book there are two grammar declarations:
explicit-member-expression -> postfix-expression . decimal-digits
explicit-member-expression -> postfix-expression . identifier generic-argument-clause[opt]
The first one is used for accessing tuples:
var tuple = (1, 2, 3)
tuple.1 = tuple.2
The second one is used for accessing other members like properties and functions:
struct S {
var property = 0
func function<T>(parameter: T) {}
}
S().property
S().function(3)
However I couldn't find a use for the optional generic-argument-clause. It is prohibited after those members:
S().property<Int> // error: '>' is not a postfix unary operator
S().function<Int>(3) // error: cannot explicitly specialize a generic function
So in which case can we use the generic-argument-clauses?
Generic argument clauses for member expressions of modules
It is possible that the generic-argument-clause only has a use case for modules (SomeModule.SomeGeneric<SomeType>()). From the Language Reference - Expressions:
Explicit Member Expression
An explicit member expression allows access to the members of a named
type, a tuple, or a module. It consists of a period (.) between the
item and the identifier of its member.
As an example:
/* Module 'MyLib.a' ... */
class MyClass<T> {
var foo: T?
}
/* ... elsewhere: explicit member expression to module */
MyLib.MyClass<Int>()
Curiously enough, implicit member expressions includes no grammar for generic-argument-clause[opt], which we can interpret as an implicit cursor that the latter, for explicit member expressions, does not concern, at the very least, enumerations; possibly slightly boosting the theory that this only concerns modules.
Grammar Of A Implicit Member Expression
implicit-member-expression → .­identifier­
Other use cases, beyond that of modules?
I can't say for sure that the above is applicable only for modules, but I haven't been able to find any other uses of generic argument clauses in the context of member expressions.
Below follows some relevant reference extracts in a somewhat discussive context; it can perhaps hold some value for others' investigation into this, beyond that of modules.
First of all, what is a generic argument clause? From Language Reference - Generic Parameters and Arguments - Generic Argument Clause
A generic argument clause specifies the type arguments of a generic type.
...
The generic argument list is a comma-separated list of type arguments.
A type argument is the name of an actual concrete type that replaces a
corresponding type parameter in the generic parameter clause of a
generic type. The result is a specialized version of that generic
type.
...
The specialized version of the generic Dictionary type,
Dictionary<String, Int> is formed by replacing the generic
parameters Key: Hashable and Value with the concrete type
arguments String and Int.
Now, the same section wraps up with the following statement:
As mentioned in Generic Parameter Clause, you don’t use a generic
argument clause to specify the type arguments of a generic function
or initializer.
We jump to the Generic Parameter Clause section and read:
... In contrast with generic types, you don’t specify a generic
argument clause when you use a generic function or initializer. The
type arguments are instead inferred from the type of the arguments
passed to the function or initializer.
So for the subject of this question, we should focus on the combination of member expressions and (for the right hand side of the .) generic types; not generic functions. But in what context---in addition to modules---can we combine these two and generic arguments clauses? The first that might come to mind is an enum with an associated generic type:
enum Bar<T> {
case One(T)
case Two
}
var foo = Bar.One(1)
print(foo.dynamicType) // Bar<Int>
But this is type inference, not generic argument clauses.
From the above, I can only think of modules as the use case for grammar generic-argument-clause in the context of member expressions.

Why can't I use 'Type' as the name of an enum embedded in a struct?

The following fails to compile:
struct S1 {
enum Type {
case One, Two, Three
}
let e1 : Type
let i : Int
}
func f1(e : S1.Type) {
S1(e1: e, i: 1)
}
with error:
error: cannot invoke initializer for type 'S1' with an argument list of type '(e1: S1.Type, i: Int)'
S1(e1: e, i: 1)
^
note: expected an argument list of type '(e1: S1.Type, i: Int)'
S1(e1: e, i: 1)
However, if I replace Type for the name of the enum with something else, say Types, it compiles fine.
Why can't I use Type as the name of an enum embedded in a struct?
You can do it like this (as mentioned before, Type is also used within the core of Swift. That's why the compiler is kind of confused). Type used as a name works if the enum is not nested:
enum Type {
case One, Two, Three
}
struct S1 {
let e1 : Type
let i : Int
}
func f1(e : Type) {
var x = S1(e1: Type.One, i: 1)
}
f1(Type.One)
if you use another name for the enum, you can still nest it:
struct S2 {
enum Kind {
case One, Two, Three
}
let e1 : Kind
let i : Int
}
func f2(e : S2.Kind) {
var x = S2(e1: S2.Kind.One, i: 1)
}
f2(S2.Kind.One)
Steve was right, it's a keyword. Here's the relevant part of the spec:
Keywords reserved in particular contexts: associativity, convenience,
dynamic, didSet, final, get, infix, inout, lazy, left, mutating, none,
nonmutating, optional, override, postfix, precedence, prefix,
Protocol, required, right, set, Type, unowned, weak, and willSet.
Outside the context in which they appear in the grammar, they can be
used as identifiers.
Apparently, a top level enum Type is fine, but one embedded in a struct is not. The language reference section on Types > Metatype Types explains why:
Metatype Type
A metatype type refers to the type of any type, including class types, structure types, enumeration types, and protocol types.
The metatype of a class, structure, or enumeration type is the name of
that type followed by .Type. The metatype of a protocol type—not the
concrete type that conforms to the protocol at runtime—is the name of
that protocol followed by .Protocol. For example, the metatype of the
class type SomeClass is SomeClass.Type and the metatype of the
protocol SomeProtocol is SomeProtocol.Protocol.