Корректировка значения различаемого объекта объединения - PullRequest
1 голос
/ 09 апреля 2009

Итак, еще один дискриминированный профсоюзный вопрос: -)

Предположим, у меня есть дискриминационный союз, например: -

type Foo =
  | A of string
  | B of int
  | C of char
  | D of string

Я бы хотел использовать функцию appendStringToFoo следующим образом: -

let someVal = A("hi")
let anotherVal = D("yo")

let hiya = someVal |> appendStringToFoo "ya"
let yoyo = anotherVal |> appendStringToFoo "yo"

Где хия = А ("хия") и йойо = D ("йойо").

Очевидно, я бы также продолжал писать отдельные функции appendIntToFoo, appendCharToFoo и т. Д.

Итак, по сути, функция похожа на: -

let appendStringToFoo str fooValue =
  fooValue(fooValue.Value + str)

Что не представляется возможным.

Я не хочу сделать следующее, если я могу избежать этого: -

let appendStringToFoo str fooValue =
    match fooValue with
    | A(originalStr) -> A(originalStr + str)
    | D(originalStr) -> D(originalStr + str)

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

Есть идеи?

1 Ответ

2 голосов
/ 09 апреля 2009

Ты должен делать то, чего не хочешь.

Альтернатива была бы аналогична

  • абстрактный класс Foo
  • абстрактный класс StringyFoo: Foo {void AppendString (string); строка S; }
  • класс A: StringyFoo
  • класс D: StringyFoo
  • абстрактный класс IntyFoo: Foo
  • класс B: IntyFoo

, который потенциально избегает «исправления appendString () каждый раз, когда вы добавляете новый тип токена», но я думаю, что для лексера (где Foo = Token) вы будете в целом счастливее с DU.

Как правило, при использовании лексирования / синтаксического анализа, независимо от того, используете ли вы иерархии классов и шаблон Visitor, или используете алгебраические типы данных, вы всегда должны писать N * M-код для N объектов и M подтипов; избежать этого нельзя, поэтому не пытайтесь найти милые уловки, пытаясь избежать этого, это только приводит к страданиям.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...