When trying to initialize a Type to \int(), as found in http://tutor.rascal-mpl.org/Rascal/Libraries/analysis/m3/Core/modifiers/modifiers.html#/Rascal/Libraries/lang/java/m3/AST/Declaration/Declaration.html , rascal throws an error saying "Expected Type, but got TypeSymbol".
This is the code I used:
Type inttype = \int();
What is the proper way to initialize a Type variable to \int()?
To solve the problem you can write:
Type myIntType = Type::\int();
More explanation follows. The \int() constructor is defined at least twice in different places:
In the abstract syntax tree definition of Java types that are used in Declarations. It is the representation of the word int in source code.
In the TypeSymbol definition in java::lang::m3::Core. There \int() represents a symbolic type.
They have the same name because they point to the same concept, but in different representations. The first is just used for a direct representation of source code, the second is used for its abstract symbolic interpretation.
To distinguish between the two representations you should either import the module that defines the AST nodes, or import the module that defines the TypeSymbols. If you happen to have both imported, you should choose a representation explicitly:
Type myIntType = Type::\int();
TypeSymbol mySymbol = TypeSymbol::\int();
So to finally explain the error message, the system chose the second kind of \int()` in TypeSymbol to build a value, and you tried to assigned it to a variable of the first kind.
\int() is a TypeSymbol, I think you're looking for
Type inttype = int();
Related
I'm confused as to the uses of "as" keyword.
Is it a cast operator or alias operator?
I encountered the following code on the internet which looked like a cast operator:
var list = json['images'] as List;
What does this mean?
as means different things in different contexts.
It's primarily used as a type cast operator. From the Dart Language Tour:
as: Typecast (also used to specify library prefixes)
It links to an explanation of how as is also used to add a prefix to an imported library to avoid name collisions. (as was reused to do different things to avoid needing extra keywords.)
just to add the as keyword is now flagged by the linter and they prefer you to use a check like is
if (pm is Person)
pm.firstName = 'Seth';
you can read more here https://github.com/dart-lang/linter/issues/145
As the language tour says:
Use the as operator to cast an object to a particular type if and only if you are sure that the object is of that type.
Following with your example:
var list = json['images'] as List;
You would use as here to cast or convert json['images'] into a <List> object.
From another SO post (talking about explicit cast vs. as):
as ... is more like an assertion, if the values type doesn't match as causes a runtime exception.
You can also use it when importing packages. A common example is the dart:convert as JSON which then can be reached final foo = JSON.jsonDecode(baz)
It's casting, your code is similar as:
List list = json['images'];
I just started to study F# and accidentally wrote this binding
let List = 1
Now when I try to obtain List methods such as 'filter' I get this error
error FS0039: The field, constructor or member 'filter' is not defined.
Of course using method with full type name like Microsoft.FSharp.Collections.List.filter is still working.
I'm wondering why it is possible to use type name as identifier in F# and how I can set back name List to type List from Microsoft.FSharp.Collections.
When I tried to reassign like this
type List = Microsoft.FSharp.Collections.List<'T>
I get
Error FS0039: The type parameter 'T is not defined.
Thank you!
In F# you can redefine almost everything and shadow existing definitions. This applies to both types (well actually types have a different behavior regarding shadowing, they shadow their values as you open the namespaces) and values but not interchangeably since values and type (and also modules) can somehow coexist at the same time in the scope. The compiler will do his best to find out which one is.
You are not forced to, but it's a common good practice in F# not to use let bindings in uppercase.
Regarding your second question, you are using a type parameter in the right side which doesn't exist in the left side of the assignment, it should be:
type List<'T> = Microsoft.FSharp.Collections.List<'T>
But notice that filter doesn't belong to the type. It's rather defined in the List module.
You should just rename your let binding from List to something sensible - as Gustavo mentioned, your definition is shadowing the core List module from F# and there is no way to use List to refer both to your integer and to the module. Shadowing core functions will make your code pretty confusing. It's also a good idea to use camelCase for let bindings, but that's a matter of taste.
If you insist on shadowing List, then you won't be able to call List.filter using List.filter. If you wanted something shorter, you could define module alias:
module FsList = Microsoft.FSharp.Collections.List
Note that your attempt to do something similar with List<'T> does not do the same thing, because functions such as filter are in a module named List rather than being static members of the type. With this, you can call filter using FsList.filter.
I'm trying to write a Vapi file for MessagePack and am having a couple of issues, the first being that the resulting msgpack_object_print is incorrect because of the reference type of one of the parameters. The header file expects
void msgpack_object_print(FILE* out, msgpack_object o);
and my Vapi file contains
[CCode (instance_pos = 1.1)]
public void print (Posix.FILE out);
which generates the C output
msgpack_object_print (_tmp13_, &obj);
where obj is type msgpack_object *. This creates the error
examples/simple.c:173:34: error: incompatible type for argument 2 of ‘msgpack_object_print’
and it disappears if I remove the & from the generated C. So I'm wondering what my Vapi should contain to result in the correct output?
You can designated your msgpack_object class as [SimpleType] and it will be copied by value rather than by reference.
I have written a partial VAPI for MessagePack if you want to contribute back by using and testing it.
https://github.com/valum-framework/vala-extra-vapis/blob/msgpack/msgpack.vapi
Like already said, you need to use the [SimpleType] annotation on the class to have your type passed by value.
EDIT: Just adding that for bindings, it's a good thing to keep them in nemequ/vala-extra-vapis repository.
In a fsyacc based project, I have this line:
type 'a cucomment = string
This is the full error description I'm getting:
CALast.fs(117,9): error FS0035: This construct is deprecated: This
type abbreviation has one or more declared type parameters that do not
appear in the type being abbreviated. Type abbreviations must use all
declared type parameters in the type being abbreviated. Consider
removing one or more type parameters, or use a concrete type
definition that wraps an underlying type, such as 'type C<'a> = C of
...'.
Any idea how to solve this?
F# no longer allows type aliases that add generic type parameters to a type without declaring a new type. If you want to define a generic type that wraps some other type, you have to use some constructor. For example, you can use single-case discriminated union:
type 'a Cucomment = CC of string
Unfortunately, this means that you'd have to change all code that uses the type to unwrap the value using pattern matching or by adding Value member to the type.
The only case where generic type aliases are allowed is when you declare a version of type with units of measure, which requires a special attribute. However, this is probably not going to work for you (because units behave quite differently):
[<MeasureAnnotatedAbbreviation>]
type 'a Cucomment = string
If this is in some code generated by fsyacc, then that's a bug in fsyacc that should be fixed (I think this was quite recent change). In that case, report it to fsbugs at microsoft dot com.
I know I must be missing something really obvious here. B.GetInstance().Call() generates the error: Lookup on object of indeterminate type based on information prior to this program point. A type annotation may be needed prior to this program point to constrain the type of the object. This may allow the lookup to be resolved.
I'm using v1.9.9.9.
type A() =
member x.Call() = B.GetInstance().Call()
and B() =
static member GetInstance() = new B()
member x.Call() = ()
I just discovered that this works: (B.GetInstance() :> B).Call()
Any idea why the cast is necessary?
Frequently when you've got a recursive set of methods whose types to infer, F# needs help. A more pleasant alternative would be to annotate the definition of B.GetInstance:
type A() =
member x.Call() = B.GetInstance().Call()
and B() =
static member GetInstance() : B = new B()
member x.Call() = ()
I believe that the reason you run into this problem is that F# tries to solve all inferred types on all methods in A and B simultaneously (because they are defined as mutually recursive types), and this leads to problems, but perhaps someone from the F# team will weigh in.
The quick summary is that in a recursive group (e.g. members in one type, or members of recursive types like we have here) F# reads the declarations in left-to-right top-to-bottom order, followed by the definitions in left-to-right top-to-bottom order. So in this instance when it reaches the definition of A.Call, it has not yet read the definition of B.GetInstance and therefore does not (yet!) know that the return type of GetInstance will be B.
Keith's answer nails it for this situation, you can provide a type annotation to specify the return type of GetInstance in its declaration.
See
Forcing F# type inference on generics and interfaces to stay loose
for a deep discussion of what's going on here.
Note also that in your original attempt, you don't need to "cast" (the potentially dynamic operation, using :>), instead you can just "annotate" (statically declare a type, using :) to get it to compile. But makes more sense to put the type annotation in the method declaration for GetInstance (generally, prefer addition annotations to method signatures instead of arbitrary places inside bodies).