Generic 通过什么机制与 Aeson 的 ToJSON class 交互?
By what mechanism does Generic interact with Aeson's ToJSON class?
查看 servant
example 的一部分,我看到:
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeOperators #-}
module Main where
import Prelude ()
import Prelude.Compat
import Control.Monad.Except
import Control.Monad.Reader
import Data.Aeson.Types
import Data.Attoparsec.ByteString
import Data.ByteString (ByteString)
import Data.List
import Data.Maybe
import Data.String.Conversions
import Data.Time.Calendar
import GHC.Generics
import Lucid
import Network.HTTP.Media ((//), (/:))
import Network.Wai
import Network.Wai.Handler.Warp
import Servant
import System.Directory
import Text.Blaze
import Text.Blaze.Html.Renderer.Utf8
import qualified Data.Aeson.Parser
import qualified Text.Blaze.Html
type UserAPI1 = "users" :> Get '[JSON] [User]
data User = User
{ name :: String
, age :: Int
, email :: String
, registration_date :: Day
} deriving (Eq, Show, Generic)
instance ToJSON User
当我删除 Generic
的 deriving
时,出现以下错误:
• No instance for (Generic User)
arising from a use of ‘aeson-1.1.2.0:Data.Aeson.Types.ToJSON.$dmtoJSON’
因此,我假设 User
的 Generic
类型类实例使 instance ToJSON User
能够创建一个 JSON Encoder
User
.
instance ToJSON User
的机制是什么,即类型签名,如果这是正确的词?
我试图从 stack ghci
查看它的类型,即 REPL,但失败了:
λ: >:t instance
<interactive>:1:1: error: parse error on input ‘instance’
λ: >:i instance
<interactive>:1:1: error: parse error on input ‘instance’
让我们看看 the source ToJSON
:
class ToJSON a where
-- | Convert a Haskell value to a JSON-friendly intermediate type.
toJSON :: a -> Value
default toJSON :: (Generic a, GToJSON Zero (Rep a)) => a -> Value
toJSON = genericToJSON defaultOptions
ToJSON
class 有一个默认的 toJSON
实现,带有额外的类型约束(包括 Generic
,如您所见)。这需要 DefaultSignatures
扩展;注意在那个模块的顶部你可以看到
{-# LANGUAGE DefaultSignatures #-}
另一个约束 GToJSON Zero (Rep a)
对 a
的结构施加了一些进一步的限制,因此不是 每个 类型 Generic
实例将满足此签名。
关于您关于 GHCi 的问题:instance
是一个 Haskell 关键字。检查 toJSON
可能是您想要的。这将向您显示我们在源代码中看到的相同信息:
λ> :i toJSON
class ToJSON a where
toJSON :: a -> Value
default toJSON :: (GHC.Generics.Generic a,
GToJSON Zero (GHC.Generics.Rep a)) =>
a -> Value
...
-- Defined in ‘aeson-1.1.2.0:Data.Aeson.Types.ToJSON’
查看 servant
example 的一部分,我看到:
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeOperators #-}
module Main where
import Prelude ()
import Prelude.Compat
import Control.Monad.Except
import Control.Monad.Reader
import Data.Aeson.Types
import Data.Attoparsec.ByteString
import Data.ByteString (ByteString)
import Data.List
import Data.Maybe
import Data.String.Conversions
import Data.Time.Calendar
import GHC.Generics
import Lucid
import Network.HTTP.Media ((//), (/:))
import Network.Wai
import Network.Wai.Handler.Warp
import Servant
import System.Directory
import Text.Blaze
import Text.Blaze.Html.Renderer.Utf8
import qualified Data.Aeson.Parser
import qualified Text.Blaze.Html
type UserAPI1 = "users" :> Get '[JSON] [User]
data User = User
{ name :: String
, age :: Int
, email :: String
, registration_date :: Day
} deriving (Eq, Show, Generic)
instance ToJSON User
当我删除 Generic
的 deriving
时,出现以下错误:
• No instance for (Generic User)
arising from a use of ‘aeson-1.1.2.0:Data.Aeson.Types.ToJSON.$dmtoJSON’
因此,我假设 User
的 Generic
类型类实例使 instance ToJSON User
能够创建一个 JSON Encoder
User
.
instance ToJSON User
的机制是什么,即类型签名,如果这是正确的词?
我试图从 stack ghci
查看它的类型,即 REPL,但失败了:
λ: >:t instance
<interactive>:1:1: error: parse error on input ‘instance’
λ: >:i instance
<interactive>:1:1: error: parse error on input ‘instance’
让我们看看 the source ToJSON
:
class ToJSON a where
-- | Convert a Haskell value to a JSON-friendly intermediate type.
toJSON :: a -> Value
default toJSON :: (Generic a, GToJSON Zero (Rep a)) => a -> Value
toJSON = genericToJSON defaultOptions
ToJSON
class 有一个默认的 toJSON
实现,带有额外的类型约束(包括 Generic
,如您所见)。这需要 DefaultSignatures
扩展;注意在那个模块的顶部你可以看到
{-# LANGUAGE DefaultSignatures #-}
另一个约束 GToJSON Zero (Rep a)
对 a
的结构施加了一些进一步的限制,因此不是 每个 类型 Generic
实例将满足此签名。
关于您关于 GHCi 的问题:instance
是一个 Haskell 关键字。检查 toJSON
可能是您想要的。这将向您显示我们在源代码中看到的相同信息:
λ> :i toJSON
class ToJSON a where
toJSON :: a -> Value
default toJSON :: (GHC.Generics.Generic a,
GToJSON Zero (GHC.Generics.Rep a)) =>
a -> Value
...
-- Defined in ‘aeson-1.1.2.0:Data.Aeson.Types.ToJSON’