Как преобразовать экземпляр generi c вариантов без совпадений с избыточностью? - PullRequest
2 голосов
/ 04 мая 2020

У меня есть следующий универсальный c тип варианта:

type 'a t = A | B | C | D | E | Value of 'a

и некоторая функция, которая преобразует int t в string t

let int_to_sting = function
  | Value x -> Value (string_of_int x)
  | some    -> some

Эта функция не компилируется из-за

| some -> some
Ошибка: это выражение имеет тип int t, но ожидалось выражение типа string t
Тип int несовместим

Даже если оно имеет Тип аннотации.

let int_to_sting : int t -> string t = function
  | Value x -> Value (string_of_int x)
  | some    -> some

Я могу переписать его с

let int_to_sting = function
  | Value x -> Value (string_of_int x)
  | A       -> A
  | B       -> B
  | C       -> C
  | D       -> D
  | E       -> E 

Но длинный список конструкторов выглядит избыточно. Можно ли преобразовать some в моей первой реализации, чтобы избежать этого шумного кода?

1 Ответ

3 голосов
/ 04 мая 2020

Вы можете сделать его немного менее избыточным, перечислив и , привязав их к имени:

let int_to_sting = function
  | Value x -> Value (string_of_int x)
  | (A | B | C | D | E) as some -> some

Другой вариант, который ЯВНО НЕ БЕЗОПАСЕН, и который ВЫ ОПРЕДЕЛЕННО НЕ ДОЛЖНЫ ИСПОЛЬЗОВАТЬ это обойти систему типов, используя Obj.magic:

let int_to_sting = function
  | Value x -> Value (string_of_int x)
  | some    -> (Obj.magic (some: int t): string t)

Это работает, потому что представление этих значений одинаково, независимо от аргумента типа. Но если вы добавите еще один конструктор, который не ... тогда вы создадите sh и сожжете.

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