Вяз: доступ к общим полям в союзе - PullRequest
1 голос
/ 05 июля 2019

Я пытаюсь смоделировать тип как объединение, в котором каждый член этого объединения имеет общие свойства со всеми другими членами.

Я сейчас достигаю этого примерно так:

type alias File = {
    name : String
  }

type CommonFileState extra = CommonFileState {
    id : String
  , file : File
  } extra

type alias ValidFileState = CommonFileState {
    validatedAt : Int
  }
type alias InvalidFileState = CommonFileState {
    reason : String
  }
type alias LoadingFileState = CommonFileState {}

type FileState = Valid ValidFileState | Invalid InvalidFileState | Loading LoadingFileState

Теперь, если я хочу прочитать одно из этих общих свойств для любого заданного FileState, я должен сопоставить каждого члена объединения:

getId : FileState -> String
getId fileState = case fileState of
  Valid (CommonFileState {id} extra) -> id
  Invalid (CommonFileState {id} extra) -> id
  Loading (CommonFileState {id} extra) -> id

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

Я хочу иметь возможность легко получать доступ к общим свойствам моего объединения и работать с этими общими свойствами.

Когда я начал искать другие способы сделать это, я обнаружил, что одной из альтернатив было вложить объединение в запись, которая также содержит общие свойства:

type alias ValidCurrentFileState = {
    validatedAt : Int
  }
type alias InvalidCurrentFileState = {
    reason : String
  }
type alias LoadingCurrentFileState = {}

type CurrentFileState = Valid ValidCurrentFileState | Invalid InvalidCurrentFileState| Loading LoadingCurrentFileState

type alias File = {
    name : String
  }

type alias FileState = {
    id : String
  , file : File
  , currentState : CurrentFileState
  }

getId : FileState -> String
getId {id} = id

Однако это неудобно, потому что я должен назвать вложенное объединение, которое добавляет уровень ненужной косвенности: «состояние файла» и « текущее состояние файла» концептуально совпадают.

Есть ли другие способы сделать это, у которых нет проблем, о которых я говорил?

1 Ответ

1 голос
/ 07 июля 2019

Я думаю, вы думаете об этом неправильно.

Цель моделирования (в Elm) - захватить возможные состояния ваших данных и исключить - в вашей модели - «невозможные» состояния, чтобы компилятор мог статически предотвращать код при каждом создании таких состояний.

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

Я подозреваю, что обычно я бы пошел с вашим вторым подходом,но я не знаю всех проблем, которые нужно учитывать.

...