我有两种类型,它们共享一个命名值。
type Type1 =
{
p1: int;
p2: int;
}
type Type2 =
{
p1 : int;
p3 : int;
}
是否可以创建仅更改此命名值(p1)并返回新记录的函数?
我试过这么远:
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)
这不起作用,因为编译器假定{value with p1 = 10}是Type2,它可能是。
如果有更好更聪明的解决方案,那也会有所帮助。
我知道如果我对我的类型使用mutable或者使用类而不是简单的记录,这是可能的,但我想知道是否有更好的方法来处理它而不是OO方法。
答案 0 :(得分:0)
我的意思是,你可以试试这个......
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
iTypeToWrapper功能的问题在于,如果您传递的内容不是Type1
或Type2
,则会失败。要解决此问题,如果您的用例可以使用选项,则可以使用以下内容。
// 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