Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Record transformation

Tags:

f#

Suppose I have the following type:

type Temp<'b,'c> =
   {
      A : string
      B : 'b
      C : 'c
      D : string
   }

And I want to create a function that receives Temp<string,string> and outputs Temp<int,int>. I tried two approaches. The most cumbersome (f1) works and the most logical (in my view) does not (f2).

let f1 (r : Temp<string,string>) = //works
    {
       A = r.A
       B = r.B |> int
       C = r.C |> int
       D = r.D
    }

//doesn't work
let f2 (r : Temp<string,string>) = {r with B = r.B |> int; C = r.C |> int}

Is there another way to construct such a function without having to repeat all the fields in the body?

like image 635
FRocha Avatar asked Oct 17 '25 00:10

FRocha


1 Answers

As mentioned before, you can not (ATM) use the f2 approach but you can simply create a generic version of your f1 approach and use it.

type Temp<'b,'c> = {
    A: string
    B: 'b
    C: 'c
    D: string
}

module Temp =
    let bind fB fC temp =
        {
            A = temp.A
            B = fB temp.B
            C = fC temp.C
            D = temp.D
        }

    let bind1 f = bind f f

let sTemp: Temp<string, string> = {
    A = "a"
    B = "b"
    C = "c"
    D = "d"
}

let iTemp: Temp<int, int> = sTemp |> Temp.bind int int   // with two separate functions for each generic field

let iTemp: Temp<int, int> = sTemp |> Temp.bind1 int      // with one function for both fields at once
like image 97
Mortal Flesh Avatar answered Oct 18 '25 22:10

Mortal Flesh