Haskell 如何为种类为(*->;*)->;的类型编写aeson到JSON实例* 动机

Haskell 如何为种类为(*->;*)->;的类型编写aeson到JSON实例* 动机,haskell,aeson,Haskell,Aeson,我有一个类型,MyType,它由一个函子,f参数化 我想使用MyType-Identity来表示数据的“我的视图”,而MyType-Maybe则表示数据更新的类型 问题 是否可以为MyType编写aesonToJSON实例?我试图使用ToJSON类,但出现了一个错误(请参阅本文底部) 对于任意的f,如何获取MyType f的ToJSON实例 编译错误 在评论剥削阶级时使用了我的想法,经过一些修补之后,我得出了这个结论 {-# LANGUAGE DeriveGeneric ,

我有一个类型,
MyType
,它由一个函子,
f
参数化

我想使用
MyType-Identity
来表示数据的“我的视图”,而
MyType-Maybe
则表示数据更新的类型

问题 是否可以为
MyType
编写aeson
ToJSON
实例?我试图使用
ToJSON
类,但出现了一个错误(请参阅本文底部)

对于任意的
f
,如何获取
MyType f
的ToJSON实例

编译错误
在评论剥削阶级时使用了我的想法,经过一些修补之后,我得出了这个结论

{-# LANGUAGE DeriveGeneric
           , FlexibleContexts   
           , MultiParamTypeClasses
           , ScopedTypeVariables
           , TypeApplications
           , UndecidableInstances 
           #-}
module Main where

import GHC.Generics
import Data.Aeson
import Data.Constraint
import Data.Constraint.Lifting

data MyType f = MyType
  { age  :: f Int
  , name :: f String
  } deriving(Generic)

instance (Lifting ToJSON f) => ToJSON (MyType f) where
    toJSON mt
        | Sub Dict <- lifting @ToJSON @f @Int
        , Sub Dict <- lifting @ToJSON @f @String
            = genericToJSON defaultOptions mt

instance Lifting ToJSON Maybe where
    lifting = Sub Dict

main :: IO ()
main = print . encode $ MyType (Just 1) (Just "hi")
{-#派生通用语言
,灵活的语境
,multiparamTypeClass
,ScopedTypeVariables
,打字应用
,不可判定的实例
#-}
模块主要在哪里
进口GHC.仿制药
导入数据.Aeson
导入数据。约束
导入数据.Constraint.Lifting
数据MyType f=MyType
{age::f Int
,name::f字符串
}派生(通用)
实例(提升ToJSON f)=>ToJSON(MyType f),其中
东山

|子目录看起来您需要知道所有a的
。ToJSON a=>ToJSON(FA)
。也许一个约束符合要求?我不熟悉约束-你能给我指一些阅读材料吗,或者告诉我添加约束在语法上看起来如何?(或者两者都有!)@luqui:难道你不能用
QuantifiedConstraints
在GHC 8.6中直接表达出来吗?@JonPurdy?我还没玩过呢。这看起来很合适——不过我得读点书!谢谢
Main.hs:12:10: error:
    • Could not deduce (ToJSON (f String))
        arising from a use of ‘aeson-1.2.4.0:Data.Aeson.Types.ToJSON.$dmtoJSON’
      from the context: ToJSON1 f
        bound by the instance declaration
        at Main.hs:12:10-39
    • In the expression:
        aeson-1.2.4.0:Data.Aeson.Types.ToJSON.$dmtoJSON @MyType f
      In an equation for ‘toJSON’:
          toJSON = aeson-1.2.4.0:Data.Aeson.Types.ToJSON.$dmtoJSON @MyType f
      In the instance declaration for ‘ToJSON (MyType f)’
   |
12 | instance ToJSON1 f => ToJSON (MyType f)
   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Failed, no modules loaded.
{-# LANGUAGE DeriveGeneric
           , FlexibleContexts   
           , MultiParamTypeClasses
           , ScopedTypeVariables
           , TypeApplications
           , UndecidableInstances 
           #-}
module Main where

import GHC.Generics
import Data.Aeson
import Data.Constraint
import Data.Constraint.Lifting

data MyType f = MyType
  { age  :: f Int
  , name :: f String
  } deriving(Generic)

instance (Lifting ToJSON f) => ToJSON (MyType f) where
    toJSON mt
        | Sub Dict <- lifting @ToJSON @f @Int
        , Sub Dict <- lifting @ToJSON @f @String
            = genericToJSON defaultOptions mt

instance Lifting ToJSON Maybe where
    lifting = Sub Dict

main :: IO ()
main = print . encode $ MyType (Just 1) (Just "hi")