Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generically add field to anonymous record using a function

I would like to be able to take an arbitrary record as a parameter and return an anonymous record with a field added using the copy-and-update syntax.

For example, this works:

let fooBar =
  {| Foo = ()
     Bar = () |}

let fooBarBaz = {| fooBar with Baz = () |}

But I would like to do this:

let fooBar =
  {| Foo = ()
     Bar = () |}

let inline addBaz a = {| a with Baz = () |} (* The input to a copy-and-update expression that creates an anonymous record must be either an anonymous record or a record *)

let fooBarBaz = addBaz fooBar

Is there a way to do this in F#?

like image 668
Lyndon Gingerich Avatar asked Oct 19 '25 12:10

Lyndon Gingerich


1 Answers

No, that's not possible.

Think about it, if that function was possible, what would be the type ? Is it something that "fits" into existing F# type system?

The type should be something like val addField: x: {| FieldName<1>: 't1; FieldName<2>: 't2; ... FieldName<n>: 'tn;|} -> {| FieldName<1>: 't1; FieldName<2>: 't2; ... FieldName<n>: 'tn; Baz: unit |}

Clearly something like that's not representable in F# type system.

UPDATE

It was mentioned that adding a record constraint would allow this but this is quite far from reality. A record constraint would just filter the argument to be a record but the problem which remains is how do the type system express that the function takes a type ^T when ^T : record and returns something like ^U when ^U : ^T_butWithAnAdditionalField

Also, on the SRTP side there is a way to "read" a field by adding a get_FieldName constraint but not to write, moreover the possibility to read a field allow us to read a field of a known name, not any name.

Conclusion: F# type system is very far away from allowing to express stuff like this and the SRTP mechanism is not there either.

Allowing an "is record" constraint shouldn't be that complicated but it won't solve anything here.

like image 170
Gus Avatar answered Oct 21 '25 10:10

Gus



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!