#f#
#f#
Вопрос:
У меня есть такие типы, как этот:
type Workshop = { Start: DateTime; End: DateTime } type Mounting = { Start: DateTime; End: DateTime } type FixedWorkTime = { Start: DateTime; End: DateTime } type WorkTime = | Workshop of Workshop | Mounting of Mounting type ApprovedWorkTime = | ExistingWorkTime of WorkTime | FixedWorkTime of FixedWorkTime
Теперь я хочу создать функцию с этой подписью WorkTime -gt; ApprovedWorkTime
let FixWorkTime (workTime: WorkTime) : ApprovedWorkTime = match workTime with | WorkTime.Workshop workshop -gt; ApprovedWorkTime.ExistingWorkTime { Start = workshop.Start, End = workshop.End } | WorkTime.Mounting mounting -gt; ApprovedWorkTime.FixedWorkTime { Start = mounting.Start, End = mounting.End }
match
Не удается выполнить компиляцию с этой ошибкой:
This expression was expected to have type 'WorkTime' but here has type 'FixedWorkTime'
Как я могу это исправить?
Ответ №1:
Используйте точки с запятой, а не запятые, между полями записей. Всякий раз, когда вы видите запятую, предполагайте, что это означает кортеж.
Во-вторых, существующее рабочее время относится к рабочему времени, которое также является DU, поэтому у вас есть иерархия.
let fixWorkTime (workTime: WorkTime) : ApprovedWorkTime = match workTime with | Workshop workshop -gt; ExistingWorkTime (Workshop { Start = workshop.Start; End = workshop.End }) | Mounting mounting -gt; FixedWorkTime { Start = mounting.Start; End = mounting.End }
Ответ №2:
Простое решение заключается в том, чтобы привести типы в соответствие, как уже объяснялось в других ответах:
let FixWorkTime (workTime: WorkTime) : ApprovedWorkTime = match workTime with | WorkTime.Workshop _ -gt; ExistingWorkTime workTime | WorkTime.Mounting mounting -gt; FixedWorkTime { Start = mounting.Start; End = mounting.End }
Тем не менее, я бы, вероятно, немного изменил ваши типы, чтобы сделать их более составными:
type Interval = { Start: DateTime; End: DateTime } type WorkTime = | Workshop of Interval | Mounting of Interval type ApprovedWorkTime = | ExistingWorkTime of WorkTime | FixedWorkTime of Interval let FixWorkTime (workTime: WorkTime) : ApprovedWorkTime = match workTime with | Workshop _ -gt; ExistingWorkTime workTime | Mounting interval -gt; FixedWorkTime interval
Ответ №3:
Здесь:
ApprovedWorkTime.ExistingWorkTime { Start = workshop.Start, End = workshop.End }
Вы пытаетесь создать значение ApprovedWorkTime
с ExistingWorkTime
помощью конструктора и передаете ему запись в качестве параметра.
Но в соответствии с его определением:
| ExistingWorkTime of WorkTime
Он не ожидает записи или ожидает значения типа WorkTime
.
Таким образом, самый короткий способ исправить это-использовать его workTime
в качестве параметра:
ApprovedWorkTime.ExistingWorkTime workTime
Хотя я сильно сомневаюсь, что это то, что вы хотели сделать.
Отдельно я хотел бы отметить, что ваши типы излишне сложны. Посмотрите: каждое отдельное значение имеет одни и те же поля, и они отличаются только своими конструкторами, и вам приходится перелопачивать эти поля туда и обратно каждый раз, когда вы конвертируете значения.
Более эффективная модель будет иметь поля Start
и End
на верхнем уровне и вид работы в качестве третьего поля:
type WorkTimelt;'kindgt;= { Start: DateTime; End: DateTime; Kind: 'kind } type WorkTimeKind = Workshop | Mounting type ApprovedWorkTimeKind = ExistingWorkTime of WorkTime | FixedWorkTime