F # type restriction for a record type with a specific property

I am trying to create a generic function that requires an argument of its type that it is a record type and that it has a specific property. Here is a sample that generates the corresponding compiler error:

let foo<'a> (a : 'a) =
    a' = { a with bar = "baz" }
    a'

Having compiled this, I get an error message The record label bar is not defined.

I tried adding the following type restriction:

let foo<'a when 'a : (member Id : string)> =
    // ...

but this also did not compile, complaining that This code is not sufficiently generic. The type variable ^a when ^a : (member get_Int : ^a -> string) could not be generalized because it would escape its scope.

Is there a way to specify a type constraint that will allow me to do this correctly?

+4
source share
3 answers

. , , , . F #, .NET, - . , .

, , - :

type Test = {Bar : string}

let inline foo (a : ^a) =
    "foo " + ((^a) : (member Bar : string) (a))

let foobar = foo {Bar = "bar"} // prints "foo bar"

, , , -, Bar string. , :

type Test2(str : string) = member this.Bar = str

let foobar2 = foo (Test2("bar")) // prints "foo bar"
+5

, -. , , .

​​, , , ( , , , , , ):

type ISetA<'T> = 
  abstract WithA : string -> 'T

type MyRecord = 
  { A : string }
  interface ISetA<MyRecord> with
    member x.WithA(a) = { x with A = a }

( , , ). , ...

, :

let setA (setA:ISetA<_>) = 
  setA.WithA "Hello"

setA { A = "Test" }
+4

, .

READ , TheInnerLight.

, , , .

, , . , : .

type Test<'a> = {Bar : string; Rest : 'a}

type A = {PropA : string}
type B = {PropB : int}

let a = {Bar = "bar"; Rest  = {PropA = "propA" }}


let foo a = {a with Bar = "foo " + a.Bar}

let foobar = foo {Bar = "bar"; Rest = {PropA = "propA"}} 
// val foobar : Test<A> = {Bar = "foo bar"; Rest = {PropA = "propA";};}

let foobar' = foo {Bar = "bar"; Rest = {PropB = 0}}
// val foobar' : Test<B> = {Bar = "foo bar"; Rest = {PropB = 0;};}

, , .

+2

All Articles