Как деконструировать союз с "с"? - PullRequest
0 голосов
/ 01 марта 2019

У меня есть некоторые проблемы при использовании «с» с дискриминированным объединением:

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" }

Теперь я хочу изменить Имя2 на Нет, но я не мог понять, как.Что-то вроде:

let company2 = Company { company with Name2 = None }

В моем "примере из реального мира" это, конечно, вложено, иначе я мог бы использовать правильный тип.

Может быть, это невозможно, потому что я долженсопоставление с образцом для граничного случая, который не может существовать (но компилятор недостаточно умен, чтобы знать).

Ответы [ 2 ]

0 голосов
/ 01 марта 2019

Если разбить его еще немного, проблему легче увидеть.На самом деле, вероятно, это затрудняет присвоение имен.

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 }

Надеюсь, это поможет.

0 голосов
/ 01 марта 2019

Вот как вы это сделаете (я предполагаю, что если переменная company равна NaturalPerson, то вы хотите, чтобы она не изменилась):

match company with
| Person _ -> company
| Company corpEntity -> Company { corpEntity with Name2 = None }
...