Какая-нибудь приятная запись с трюками в Haskell? - PullRequest
3 голосов
/ 23 января 2012

Мне известны частичные обновления таких записей, как:

data A a b = A { a :: a, b :: b }
x = A { a=1,b=2 :: Int }
y = x { b = toRational (a x) + 4.5 }

Существуют ли уловки для выполнения только частичной инициализации, создания типа подзаписи или (де) сериализации для подзаписи?

В частности, я обнаружил, что первая из этих строк работает, а вторая - нет:

read "A {a=1,b=()}" :: A Int ()
read "A {a=1}" :: A Int ()

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

Ответы [ 2 ]

5 голосов
/ 23 января 2012

Частичная инициализация работает нормально: A {a=1} является допустимым выражением типа A Int (); экземпляр Read просто не беспокоится о том, что экземпляр Show не выводит. Поле b инициализируется значением error "...", где строка содержит информацию о файле / строке, чтобы помочь с отладкой.

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

Я не уверен, что вы подразумеваете под «субзаписью», но если вы хотите, чтобы сериализация / десериализация, которая может справиться с «обновлениями» до формата записи, содержала больше информации, но при этом могла обрабатывать старую (теперь «частичную») ) сериализации, то библиотека safecopy делает именно это.

0 голосов
/ 24 января 2012

Вы не можете оставить какое-либо значение в Haskell «неинициализированным» (в любом случае невозможно «инициализировать» его позже, поскольку Haskell является чистым).Если вы хотите предоставить значения «по умолчанию» для полей, то вы можете установить некоторое «значение по умолчанию» для своего типа записи, а затем выполнить частичное обновление этого значения по умолчанию, установив только те поля, которые вам нужны.Однако я не знаю, как бы вы просто реализовали read для этого.

...