Как мне выразить следующую идею в Haskell? Хотя синтаксис полностью составлен, вот чего я пытаюсь достичь:
- Мое приложение имеет сильно вложенные основные типы данных, причем каждый «уровень» имеет экземпляры FromJson/ToJson.
- JSON API, поддерживающий пользовательский интерфейс, имеет возможность манипулировать отдельными «уровнями вложенности», например. чтобы отредактировать адрес, вам не нужно редактировать весь заказ.
- Однако я хочу убедиться, что вместе с данными, которые были изменены пользовательским интерфейсом, полный заказ также отправляется обратно. Это гарантирует, что, если редактирование привело к изменению какого-либо зависимого поля в другой части объекта, оно будет передано обратно в пользовательский интерфейс.
Изменить. Основной вопрос не в логике приложения как таковой. Основной вопрос заключается в том, как представить ключи JSON безопасным для типов способом, имея при этом возможность их параметризации. Простое решение состоит в том, чтобы иметь разные конкретные типы для каждого типа возврата API, например, {orderItems :: [OrderItem], order :: Order}
или {address :: Address, order :: Order}
или {email :: Email, customer :: Customer}
. Но они быстро повторяются. Я хочу иметь тип данных, который представляет идею JSON с парой первичный ключ-значение и парой вторичный/поддерживающий ключ-значение, где имена ключей можно легко изменить.
Приведенный ниже псевдокод является обобщением этой идеи:
data IncomingJson rootname payload = (FromJson payload, ToString rootname) => IncomingJson
{
rootname :: payload
}
data OutgoingJson rootname payload sidename sidepayload = (ToJson payload, ToString rootname, ToJson sidepayload, ToString sidename) => IncomingJson
{
rootname :: payload
, sidename :: sidepayload
}
createOrder :: IncomingJson "order" NewOrder -> OutgoingJson "order" Order Nothing ()
editOrderItems :: IncomingJson "items" [OrderItem] -> OutgoingJson "items" [OrderItem] "order" Order
editOrderAddress :: IncomingJson "address" Address -> OutgoingJson "address" Address "order" Order