如何用 "with" 解构联合?
How to deconstruct union with "with"?
我在使用 "with" 时遇到一些问题:
type NaturalPerson = {
FirstName: string
LastName: string
}
type CorporateEntity = {
Name1: string
Name2: string option
}
type Person =
| Natural of NaturalPerson
| Company of CorporateEntity
let company = Company { Name1 = "Foo Bar AG"; Name2 = Some "Baz" }
现在我想将 Name2 更改为 None,但我不知道该怎么做。
类似于:
let company2 = Company { company with Name2 = None }
在我的 "real world example" 当然这是嵌套的,否则我可以使用正确的类型。
也许这是不可能的,因为我必须为边缘情况进行模式匹配,而这种情况不存在(但编译器不够聪明,无法知道)。
这是您的操作方法(我假设如果变量 company
是 NaturalPerson
那么您希望它保持不变):
match company with
| Person _ -> company
| Company corpEntity -> Company { corpEntity with Name2 = None }
如果你把它分解得再多一点,就更容易看出问题所在。事实上,让这一切变得困难的可能是命名。
let company = Company { Name1 = "Foo Bar AG"; Name2 = Some "Baz" } // Person
let company2 = Company { company with Name2 = None } // Person, but broken because expecting company to be type of CorporateEntity
所以您正在尝试创建一个 CorporateEntity
与 Person
类型,这两个类型是不同的。
之所以有效,是因为使用了正确的类型。
let c1 : CorporateEntity = { Name1 = "Foo Bar AG"; Name2 = Some "Baz" }
let p1 : Person = Company c1
let c2 : CorporateEntity = { c1 with Name2 = None }
let p2 : Person = Company c2
我添加了类型并更改了名称以使类型更明显。
你可以 match
这个...
match company with // <- rename company to person so it is clearer
| Natural _ -> company
| Company c -> Company { c with Name2 = None }
如果你想在一个函数中进行匹配,你可以这样做:
let noCompanyName2 (c:CorporateEntity) = // c:CorporateEntity -> Person
let { Name1 = n1; Name2 = _ } = c
let company3 = Company { Name1 = n1; Name2 = None }
company3
或者更简洁:
let noCompanyName2 ({ Name1 = n1; Name2 = _ }) = Company { Name1 = n1; Name2 = None }
希望这对您有所帮助。
我在使用 "with" 时遇到一些问题:
type NaturalPerson = {
FirstName: string
LastName: string
}
type CorporateEntity = {
Name1: string
Name2: string option
}
type Person =
| Natural of NaturalPerson
| Company of CorporateEntity
let company = Company { Name1 = "Foo Bar AG"; Name2 = Some "Baz" }
现在我想将 Name2 更改为 None,但我不知道该怎么做。 类似于:
let company2 = Company { company with Name2 = None }
在我的 "real world example" 当然这是嵌套的,否则我可以使用正确的类型。
也许这是不可能的,因为我必须为边缘情况进行模式匹配,而这种情况不存在(但编译器不够聪明,无法知道)。
这是您的操作方法(我假设如果变量 company
是 NaturalPerson
那么您希望它保持不变):
match company with
| Person _ -> company
| Company corpEntity -> Company { corpEntity with Name2 = None }
如果你把它分解得再多一点,就更容易看出问题所在。事实上,让这一切变得困难的可能是命名。
let company = Company { Name1 = "Foo Bar AG"; Name2 = Some "Baz" } // Person
let company2 = Company { company with Name2 = None } // Person, but broken because expecting company to be type of CorporateEntity
所以您正在尝试创建一个 CorporateEntity
与 Person
类型,这两个类型是不同的。
之所以有效,是因为使用了正确的类型。
let c1 : CorporateEntity = { Name1 = "Foo Bar AG"; Name2 = Some "Baz" }
let p1 : Person = Company c1
let c2 : CorporateEntity = { c1 with Name2 = None }
let p2 : Person = Company c2
我添加了类型并更改了名称以使类型更明显。
你可以 match
这个...
match company with // <- rename company to person so it is clearer
| Natural _ -> company
| Company c -> Company { c with Name2 = None }
如果你想在一个函数中进行匹配,你可以这样做:
let noCompanyName2 (c:CorporateEntity) = // c:CorporateEntity -> Person
let { Name1 = n1; Name2 = _ } = c
let company3 = Company { Name1 = n1; Name2 = None }
company3
或者更简洁:
let noCompanyName2 ({ Name1 = n1; Name2 = _ }) = Company { Name1 = n1; Name2 = None }
希望这对您有所帮助。