Generic通过什么机制与Aeson的ToJSON类进行交互?

时间:2017-09-01 16:55:25

标签: haskell aeson

查看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

当我删除deriving的{​​{1}}时,我收到以下错误:

Generic

因此,• No instance for (Generic User) arising from a use of ‘aeson-1.1.2.0:Data.Aeson.Types.ToJSON.$dmtoJSON’ 的{​​{1}}类型类实例似乎启用Generic,我假设为{{1}创建了一个JSON User }。

instance ToJSON User的机制是什么,即类型签名,如果这是正确的词?

我试图从Encoder(即REPL)查看其类型,但失败了:

User

1 个答案:

答案 0 :(得分:3)

让我们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

toJSON类有一个默认的Generic实现,其中包含其他类型限制(包括{-# LANGUAGE DefaultSignatures #-} ,正如您已注意到的那样)。这需要the source扩展名;注意在该模块的顶部你可以看到

GToJSON Zero (Rep a)

另一个约束aGeneric的结构施加了一些进一步的限制,因此每个带有instance实例的类型都不会满足此要求签名。

关于GHCi的问题:toJSON是一个Haskell关键字。检查λ> :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’ 可能是你想要的。这将向您显示我们在源代码中看到的相同信息:

{{1}}