#f#
#f#
Вопрос:
F # новичок здесь. Я сказал новичок? Это мой второй день с F #)
Я хочу создать только два состояния для записи: действительное и недействительное; Я бы хотел сделать недопустимое состояние непредставимым.
Вот мой код:
module Foo =
type Success = Success of string
type Pending = Pending of string
type Failure = Failure of string
type Valid = Valid of string
type InValid = InValid of string
type StateGranted = { Status: Valid; Msg: Success }
type StateDenied = { Status: InValid; Msg: Failure }
type State =
| StateGranted
| StateDenied
let status = Valid "Valid"
let msg = Success "Success"
let state = { Status = status; Msg = msg } // I have an error here
printfn "result %A" state
Итак, как я могу создать запись типа State
?
Если пользователь хочет создать
let state = { Status = Valid; Msg = Pending } // compiler should throw an error here
У меня есть фон машинописи
PS Я нашел очень полезную статью, но я ее пока не понимаю
Ответ №1:
Я бы предложил заняться проектом в F #, где ясно, чего вы хотите достичь. Вам нужно прояснить для себя, что такое юридические данные.
-
Неясно, что
Success
представляет тип. ЯвляетсяSuccess "Invalid"
ли это законным? Это относится ко всем первым пяти типам, и их можно удалить. -
Когда вы пытаетесь определить
state
, вы, вероятно, предполагаете, что как StateGranted, так и StateDenied являются допустимыми возможностями. Но они не одного типа. Вам нужно определить один тип, который представляет то, чтоstate
может быть.
Это сводит ваш код к чему-то вроде:
[<RequireQualifiedAccess>]
type State =
| Granted // possibly you mean for there to be string-like data here
| Denied
// or possibly there are string functions of it like
//member t.ValidityString =
// match t with
// | Granted -> "Valid"
// | Denied -> "Denied"
Комментарии:
1. Спасибо, ваш ответ также очень хорош. Мне просто нужно переключить свой разум с машинописного текста на систему типов F #)
2. Да, я согласен с этим. Вам нужно унифицировать тип и, возможно, переосмыслить весь подход. Затем вы можете решить это либо с помощью сопоставления с образцом, либо с помощью активных шаблонов, если это необходимо.
Ответ №2:
У вас ошибка, потому что вывод типа не может различать две записи разных типов, но с одинаковыми свойствами. Вам нужно указать префикс одного из членов:
let state = { StateGranted.Status = status; Msg = msg }