Полиморфный тип записи в вязе - PullRequest
0 голосов
/ 20 сентября 2018

Возможно ли следующее в Elm?

func : a -> {a | id : Int}
func x = { x | id = 123 }

Не удается скомпилировать, потому что a слишком слишком полиморфный;он думает, что это может быть что угодно, включая незаписываемые типы.Как мне сказать компилятору, что a является типом записи, но для которого мы не знаем НИКАКОГО поля?(Честно говоря, мне было бы достаточно, хотя {a | id : Int} было достаточно.)

Я пытался ...

type alias Record a = {a}
func : Record a -> { a | id : Int }

func : {a} -> {a | id : Int}
func x = { x | id = 123 }

И то, и другое не работает с синтаксическими ошибками.Можно ли сказать «этот тип - запись, но я ничего не знаю» Элму?

Чтобы ответить на ответ ниже:

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

Я пытаюсь сделать что-то похожее на запись с записью неизвестных полей в моем примере, поэтому говорить, что с ними ничего нельзя сделать, неверно.

Вы не можете динамически добавлять поля в запись.

Я не динамически добавляю поле к записи, я создаю новую запись, которая соответствует существующей, за исключением того, что у нее есть поле id со значением 123.

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

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

Если это не то, что вы хотите, то, похоже, это случай проблемы XY

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

Ответы [ 3 ]

0 голосов
/ 20 сентября 2018

Нет, в Elm нет способа для аннотации типа указывать, что тип является записью, без указания каких-либо полей.Однако, даже без аннотаций типов, у Elm нет синтаксиса, чтобы делать то, что вы хотите.{ a | id = 123 } - это синтаксис обновления записи , он не поддерживает добавление полей к записи (и, начиная с Elm 0.19, также не поддерживает изменение типа поля)

Насколько я знаю, у Elm нет синтаксиса, который позволил бы вам создать копию записи с дополнительным полем.

0 голосов
/ 20 сентября 2018

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

type alias A = { a : String }
type alias B = { a : Int }
type C = Foo A
       | Bar B

type alias D = { a : C, d : Int }
fn : C -> Int -> D 
fn a y = D a y 
0 голосов
/ 20 сентября 2018

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

Выне может динамически добавлять поля в запись.Это просто не то, что делают записи, вероятно потому, что было бы очень неудобно, если бы a уже имел поле id.Таким образом, чтобы присвоить id, вам нужно знать, что запись имеет поле id.Следовательно, правильный тип функции:

func : {a | id : Int} -> {a | id : Int}

Если это не то, что вам нужно, то, похоже, это случай проблемы XY

...