Запись кросс-типа с операторами в F #? - PullRequest
2 голосов
/ 06 мая 2020

Следующий код не компилируется:

type Person = 
  {
    FirstName : string
    LastName : string
  }

type Employee = 
  {
    FirstName : string
    LastName : string
    Salary : int
  }

let p : Person = 
  {
    FirstName = "Steve"
    LastName = "Jobs"
  }

let e : Employee = 
  {
    p with Salary = 1
  }

Обходной способ - написать помощник, возможно, так:

let toEmployee (p : Person) : Employee = 
  {
    FirstName = p.FirstName
    LastName = p.LastName
    Salary = Unchecked.defaultof<_>
  }

let e : Employee = 
  {
    toEmployee p with Salary = 1
  }

Но это немного утомительно.

Предлагает ли F # лучший способ?

Это обычное дело в JavaScript, например:

const e = {
  ...p,
  salary: 1,
};

1 Ответ

4 голосов
/ 06 мая 2020

Поскольку это язык со статической и номинальной типизацией, это невозможно в F #, и это сделано намеренно.

Предположим, у вас есть такая функция, как JS и значение let e = {...p; Salary = 1}. Затем предположим, что вы переименовали поле в Person. К чему должен относиться тип e? Что должно быть сказано в сообщении об ошибке? На этот вопрос нет простых ответов, и он может стать очень сложным и трудным для понимания очень быстро в большой кодовой базе.

Лучше записать новую запись вручную. Он немного более подробный, но он соответствует общей теме F #, будучи более явным в некоторых измерениях, так что вы можете быть менее специфичными c с аннотирующими типами (позволяя больший вывод типов). Если бы вы могли быть очень неявными с обоими, это привело бы к взрыву сложности.


Другой вариант, который может помочь здесь, - изменить вашу модель, чтобы поместить повторяющиеся поля в отдельный тип:

type Person = 
  { FirstName : string
    LastName : string }

type Employee = 
  { Person : Person
    Salary : int }

let p = 
  { FirstName = "Steve"
    LastName = "Jobs" }

let e = { Person = p; Salary = 1 }

В F # способ моделирования типов очень важен и оказывает влияние на весь код, который его использует. Так что, если ваш код кажется нестабильным, подумайте, можно ли улучшить ваши типы.

...