2017-09-01 13 views
2

servantexampleの一部を見て、私は次を参照してください。GenericはAesonのToJSONクラスとどのような仕組みで対話していますか?

{-# 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 

は、私がGenericderivingを削除すると、私は次のエラーを得た:

• No instance for (Generic User) 
    arising from a use of ‘aeson-1.1.2.0:Data.Aeson.Types.ToJSON.$dmtoJSON’ 

だから、それはそのGeneric型クラスのインスタンス表示されますUserの場合instance ToJSON Userを有効にすると、UserのJSON Encoderを作成すると仮定しています。

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’ 
+1

'インスタンスToJSON User'は単なる通常のクラスインスタンスです。あなたはおそらく 'インスタンスToJSONユーザー{{}} 'を見るのに慣れています。インスタンスの本文に何もない場合は、 'where'を省略することができます(実際に' DeriveAnyClass'を有効にすると 'User'の' deriving'節に 'ToJSON'だけを置くことさえできます)。 'Generic'が" ToJSON "を有効にする理由は、' ToJSON'は[Generic'に依存するデフォルトの実装](https://hackage.haskell.org/package/aeson-1.2.1.0/docs/Data -Aeson.html#v:toJSON)。 – Alec

答えて

3

のはToJSONためthe sourceを見てみましょう:

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を含む)。これには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’ 
関連する問題