Как написать экземпляры aeson ToJSON для типов с видом (* -> *) -> *

мотивация

У меня есть тип, MyTypeкоторый параметризуется функтором MyType Identity.

Я хочу использовать MyType Maybeдля представления «моего представления» данных и ToJSONдля представления типа обновлений данных.

проблема

Можно ли написать MyTypeэкземпляр aeson ToJSON? Я пытался использовать класс, но получаю сообщение об ошибке (см. Нижнюю часть сообщения).{-# LANGUAGE DeriveGeneric #-} module Main where import GHC.Generics import Data.Aeson data MyType f = MyType { age :: f Int , name :: f String } deriving(Generic) instance ToJSON1 f => ToJSON (MyType f) main :: IO () main = print . encode $ MyType (Just 1) (Just "hi")

MyType f

Как я могу получить экземпляр для произвольного ?Main.hs:12:10: error: a€? Could not deduce (ToJSON (f String)) arising from a use of a€?aeson-1.2.4.0:Data.Aeson.Types.ToJSON.$dmtoJSONa€™ from the context: ToJSON1 f bound by the instance declaration at Main.hs:12:10-39 a€? In the expression: aeson-1.2.4.0:Data.Aeson.Types.ToJSON.$dmtoJSON @MyType f In an equation for a€?toJSONa€™: toJSON = aeson-1.2.4.0:Data.Aeson.Types.ToJSON.$dmtoJSON @MyType f In the instance declaration for a€?ToJSON (MyType f)a€™ | 12 | instance ToJSON1 f => ToJSON (MyType f) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Failed, no modules loaded.f

Ошибка компиляции

Lifting

haskell,aeson,

3

Ответов: 1


2 принят

Используя мою идею в комментарии эксплуатируя {- # LANGUAGE DeriveGeneric, FlexibleContexts, MultiParamTypeClasses, ScopedTypeVariables, TypeApplications, UndecidableInstances # -} модуль Main , где импорт GHC.Generics импорт Data.Aeson импорт Data.Constraint импорт Data.Constraint.Lifting данных MyType е = MyType { возраст :: е Int , имя :: е строки } вывод ( Generic ) экземпляр ( Подъем ToJSON f ) => ToJSON ( MyType f ), где toJSON mt | Sub Dict <- подъем @ ToJSON @ F @ Int , Sub Dict <- подъем @ ToJSON @ F @ Строка = genericToJSON defaultOptions мт например Подъемное ToJSON Может быть , где подъемная = Sub Dict главная :: IO () основной = печать . encode $ MyType ( Just 1 ) ( Just "hi" ) .html "rel =" nofollow noreferrer "> Dict class, и после некоторого вмешательства я пришел к этому

ToJSON Int

Заметки:

  • Dictпреобразует назад и вперед между ограничениями (такими как lifting @ToJSON @f @Int) и значениями. genericToJSON defaultOptionsявляется просто конструктором для вложения ограничений.
  • toJSONэто синтаксис приложения типа .
  • Я использовал lifting, просматривая реализацию по умолчаниюtoJSON . liftingСначала нам нужно было вручную перенести некоторые экземпляры в область видимости .

Надеюсь, это поможет.

Haskell, эсон,
Похожие вопросы
Яндекс.Метрика