F # Type Constraint Nonconformity when using general function constraint

In the f # project, I have the following types:

type A = { Name: string } type B = { Name: string; SurName: string } type C = { Name: string; SurName: string; MaidenName: string } 

and the following function that uses a constraint on a common argument:

 let inline filterByName<'a when 'a: (member Name: string)> (name: string) (collection: 'a seq) = collection |> Seq.where(fun i -> i.Name = name) 

The problem is that I get the following compile time error:

Limit type mismatch. A type

'a

incompatible with type

WITH

Type '' a 'does not match type' C '

Removing inline from the function definition gives me the following compile-time error:

This code is not general enough. a variable of type ^ a when ^ a: (member get_Name: ^ a → string) cannot be generalized, since it will avoid its capabilities.

What I'm trying to achieve is a function that in this case uses a common type with the property of a specific name, "Name". What am I doing wrong or what am I missing?

+5
source share
1 answer

The problem is how you invoke the restricted member - you cannot use the i.Name syntax, but should use a more detailed syntax instead. On the bright side, this allows you to display the signature of the method itself, so you do not need to duplicate everything:

 let inline filterByName name collection = collection |> Seq.where(fun i -> (^a : (member Name : string) i) = name) 

Note also that instead of a variable of the regular type ( 'a ), you need to use a statically resolved variable of the type ( ^a ).

+5
source

Source: https://habr.com/ru/post/1242227/


All Articles