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.
Related
I have read that dynamic is a data type in Dart, but is it correct to call it a data type? it doesn't seems like a data type, it seems like it is a way to allow your variable to be of any data type.
In Dart, dynamic is a type. It belongs in the type hierarchy and is related to other types by the subtype relation.
It's a "top" type, which means that every type is a subtype of dynamic. (Including itself, because the "subtype" relation is reflexive - every type is considered a subtype of itself, and the term "proper subtype" is used when only talking about subtypes that are not also supertypes.)
Being a top type, it means any value can be assigned to a variable of type dynamic. So can they to any other top type, which mainly means Object?.
The difference between the two is that:
An expression with static type dynamic can be assigned to any type. That's obviously unsafe, so the runtime inserts a check, a so called "implicit downcast" which works just like doing as TargetType.
You can call any member on an expression with static type dynamic. That's obviously unsafe, so the runtime will throw if the object doesn't have such a member.
That kind of runtime checked unsafe behavior (not static type-checked) is the reason the type is named dynamic. Using dynamic is a way to turn off the static type system. Use with extreme care.
Whether you can call dynamic a "data type" depends on what you mean by "data type". The Dart language specification doesn't use the term "data type" about anything.
Yes. The specifications call it a type (https://www.ecma-international.org/publications-and-standards/standards/ecma-408/)
The type dynamic denotes the unknown type. If no static type
annotation has been provided the type system assumes the declaration
has the unknown type
Type dynamic has methods for every possible identifier and arity, with
every possible combination of named parameters. These methods all have
dynamic as their return type, and their formal parameters all have
type dynamic. Type dynamic has properties for every possible
identifier. These properties all have type dynamic
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 use the SQL Type Provider and I'm following the approach suggested in the guidelines.
Compile vs runtime errors
I've noticed that the .MapTo<'T> convenience method is introducing runtime type-cast exceptions instead of anticipating the type checks at compile time.
Let's say we have a generic
let sel = r.MapTo<Selection>()
and compare the above with a simpler, but longer property by property assignment
sel.PacketNum <- r.PacketNum
In the latter case I get a safer and more helpful compile error, like for example:
error FS0001: This expression was expected to have type int but here has type int64
Am I missing something about the .MapTo<'T> behaviour at compile vs runtime? Is this done by or against design?
Fluent mapping and DB type assignment
I also wonder if there is the possibility (other frameworks provide such features) to
set the mapping with a property attribute or similar (what if the column name is packets instead of packet_num)?
set a different correspondence between a .Net type and a DB type (INTEGER to int instead of INT to int)?
or why it is not needed
I have a generic function where it's easy to get the compiler to infer the wrong type parameters. The type parameters only control the return type, and if I accidentally miss off a type annotation, the compiler infers obj.
How can I make it a compile-time error to call my function without giving it explicit type parameters? The Unchecked.defaultof function works the way I'd like:
> Unchecked.defaultof;;
Unchecked.defaultof;;
^^^^^^^^^^^^^^^^^^^
stdin(1,1): error FS0685: The generic function 'defaultof' must be given explicit type argument(s)
The defaultof function uses a special attribute. The F# source code is, once again, useful. The implementation of the function is in prim-types.fs, but the attribute is added in the interface file prim-types.fsi. A combined declaration would be:
[<RequiresExplicitTypeArguments>]
let inline unsafeDefault<'T> : 'T = (# "ilzero !0" type ('T) : 'T #)
The inline IL (# ... #) is limited to F# core, but the declaration is something anybody can use.
You can find the attribute in section 16 (page 217) of the F# specification:
When applied to an F# function or method, indicates that the function or method must be given explicit type arguments when used. For example, typeof<int>.
This attribute should be used only in F# assemblies.
RequiresExplicitTypeArgumentsAttribute should help