Generics and types

I have Map<ch, (int * int) list> being returned from a function. It’s used to represent a grid where a given ch has location (x,y).

I’d like to define a type to represent it, e.g
type Grid<'a> = Map<'a, (int * int) list>

but that fails with
“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 …’.”

I’m fairly new to F# and any help would be appreciated.

Thanks
Mike

Which type of map & function? give more details !

Hi Mike!

As the compiler points out, you have written a type abbreviation. This is not a new type, but just an alias for a type. With a type alias, the alias and the original type can be used interchangeably and does therefore not provide any type safety.
The compiler complains that one of the Map type parameters is a generic, but the other one ((int * int) list) is not.

In this case, you have two options (as I see it):

If you actually don’t need the type to be generic, for example if you are just playing with an Advent of Code problem, just remove the generic type and replace it with a static one. I.e.

type Grid = Map<char, (int * int) list>

The other option is to turn your type alias into an actual new type by adding a type constructor, like this:

type Grid<'a> = Grid of Map<'a, (int * int) list>

(The constructor does not need to have the same name as the type, but it’s praxis)

Then in your code, you will need to create an instance of your Grid type where you use it using the constructor:

let map = ... // Some code that gives you a Map<'a, (int * int) list>
let grid = Grid map  // Use the contructor to turn the map into your Grid type

Hope it helps :slight_smile:

1 Like

Hi Mike,

It looks like you are encountering an issue with type abbreviations in F#. To fix this, you can define a concrete type that wraps the underlying type instead of using a type abbreviation. Here’s how you can do it:

You can define a new type that wraps the Map<'a, (int * int) list>:
type Grid<'a> = Grid of Map<'a, (int * int) list>

1 Like

Thank you for helping people get the information they need. Great stuff as usual. Keep up the great work!!!

Ah, type constructor - Haskell style. Yes, thanks.

It’s a Map<ch, (int * int) list> and the function is any function that returns Map<ch, (int * int) list>

thank you for share kind of information.

thank you for sharing this information.