I have two types, and they share one named value.
type Type1 =
{
p1: int;
p2: int;
}
type Type2 =
{
p1 : int;
p3 : int;
}
Is it possible to create a function that change only this named value (p1) and returns the new record?
I tried and got this far:
type IType =
abstract member p1: int;
type Type1 =
{
p1: int;
p2: int;
}
interface IType with
member this.p1 = this.p1
type Type2 =
{
p1 : int;
p3 : int;
}
interface IType with
member this.p1 = this.p1
let changeP1ToTen (value: 'a when 'a :> IType) =
let newValue = {value with p1 = 10}
newValue
let type1 =
{
p1 = 50
p2 = 80
}
let newType1 =
changeP1ToTen(type1)
This doesn't work since the compiler assumes that {value with p1 = 10} is Type2 when it could be either.
If there is a better and clever solution it would help too.
I know this is possible if I use mutable for my types or use a class instead of a simple record but I was wondering if there was a better way to deal with it rather than the OO approach.
I mean, you could try this...
type Type1 =
{
p1 : int;
p2 : int;
}
type Type2 =
{
p1 : int;
p2 : int;
}
type Wrapper =
| TOne of Type1
| TTwo of Type2
let changeP1ToTen = function
| TOne of t1 -> { t1 with p1 = 10 }
| TTwo of t2 -> { t2 with p1 = 10 }
let type1 = { p1 = 50; p2 = 80 }
// Requires extra wrapping step, is that a dealbreaker?
let newtype1 = TOne type1 |> changeP1ToTen
// If that's a problem for ya, here's a function to fix it
let iTypeToWrapper (value: 'a when 'a :> IType) =
match value with
| :? Type1 as t1 -> TOne t1
| :? Type2 as t2 -> TTwo t2
let othernewtype1 = iTypeToWrapper type1 |> changeP1ToTen
The problem with the iTypeToWrapper function is that it will fail if you pass in something other than a Type1
or Type2
. To fix this, you can use the following, if using optionals is acceptable for your use case.
// val iTypeToWrapper : ('a when 'a :> IType) -> Wrapper option
let iTypeToWrapper (value: 'a when 'a :> IType) =
match value with
| :? Type1 as t1 -> TOne t1 |> Some
| :? Type2 as t2 -> TTwo t2 |> Some
| _ -> None
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With