レコードフィールドでHaskellの予約済みキーワードを処理する方法は?

Github Gists Rest APIに応答するJSONには、Haskellのキーワード が含まれていますtypeしかしtype、レコードフィールドとして使用することはできませんでした。

したがって、AesonのGeneric FromJSON / ToJSONインスタンス実装には使用できませんでした

import Data.Text (Text)

import GHC.Generics (Generic)

type URL = Text

data OwnerType = User deriving (Show)

data Owner = Owner {
      id :: Int,
      gravatar_id :: Text,
      login :: Text,
      avatar_url :: Text,
      events_url :: URL,
      followers_url :: URL,
      following_url :: URL,
      gists_url :: URL,
      html_url :: URL,
      organizations_url :: URL,
      received_events_url :: URL,
      repos_url :: URL,
      starred_url :: URL,
      subscriptions_url :: URL,
      url :: URL,
      -- type :: Text,
      site_admin :: Bool
  } deriving (Generic, Show)

instance ToJSON Owner
instance FromJSON Owner

質問:そのような種類の対立に対処するための適切なアプローチはありますか?

ウィレムヴァンオンセム

を使用してこれを解決できTemplateHaskellます。ToJSONandを書く代わりにFromJON、キーの特定のマッピングを使用できます。

まず、タイプでないフィールドの名前を作成する必要があります。次に例を示します。

data Owner = Owner {
      id :: Int,
      gravatar_id :: Text,
      login :: Text,
      avatar_url :: Text,
      events_url :: URL,
      followers_url :: URL,
      following_url :: URL,
      gists_url :: URL,
      html_url :: URL,
      organizations_url :: URL,
      received_events_url :: URL,
      repos_url :: URL,
      starred_url :: URL,
      subscriptions_url :: URL,
      url :: URL,
      owner_type :: Text,
      site_admin :: Bool
  } deriving (Generic, Show)

これでインスタンスderiveJSON :: Options -> Name -> Q [Dec]を作成する関数を使用できます。fromJSONtoJSON

ここでのキーはOptionsパラメーターです。これには、fieldLabelModifier :: String -> Stringフィールドの名前をJSONのキーに書き換えることができるフィールドが含まれています。したがって、ここでそれを書き換える関数を生成できます。

したがって、最初に関数を作成しますownerFieldRename :: String -> String

ownerFieldRename :: String -> String
ownerFieldRename "owner_type" = "type"
ownerFieldRename name = name

したがって、この関数"owner_type"は、にマップされて"type"いる除いて恒等関数として機能ます。

これで、次のderiveJSONようなカスタムオプションを使用し関数を呼び出すことができます。

$(deriveJSON defaultOptions {fieldLabelModifier = ownerFieldRename} ''Owner)

または完全に:

RenameUtils.hs

module RenameUtils where

ownerFieldRename :: String -> String
ownerFieldRename "owner_type" = "type"
ownerFieldRename name = name

MainFile.hs

{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE DeriveGeneric #-}

import Data.Aeson.TH(deriveJSON, defaultOptions, Options(fieldLabelModifier))
import RenameUtils(ownerFieldRename)

import Data.Text (Text)

type URL = Text

data Owner = Owner {
      id :: Int,
      gravatar_id :: Text,
      login :: Text,
      avatar_url :: Text,
      events_url :: URL,
      followers_url :: URL,
      following_url :: URL,
      gists_url :: URL,
      html_url :: URL,
      organizations_url :: URL,
      received_events_url :: URL,
      repos_url :: URL,
      starred_url :: URL,
      subscriptions_url :: URL,
      url :: URL,
      owner_type :: Text,
      site_admin :: Bool
  } deriving (Show)

$(deriveJSON defaultOptions {fieldLabelModifier = ownerFieldRename} ''Owner)

ここでtype、キーとしてJSONオブジェクトを取得します

Prelude Main Data.Aeson> encode (Owner 1 "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" True)
"{\"id\":1,\"gravatar_id\":\"\",\"login\":\"\",\"avatar_url\":\"\",\"events_url\":\"\",\"followers_url\":\"\",\"following_url\":\"\",\"gists_url\":\"\",\"html_url\":\"\",\"organizations_url\":\"\",\"received_events_url\":\"\",\"repos_url\":\"\",\"starred_url\":\"\",\"subscriptions_url\":\"\",\"url\":\"\",\"type\":\"\",\"site_admin\":true}"

単純なfieldLabelModifier関数の場合、特定の関数(特定のモジュールで定義する必要があります)を記述する必要はありません。ここでラムダ式を使用することもできます。

MainFile.hs

{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE DeriveGeneric #-}

import Data.Aeson.TH(deriveJSON, defaultOptions, Options(fieldLabelModifier))
import Data.Text (Text)

type URL = Text

data Owner = Owner {
      id :: Int,
      gravatar_id :: Text,
      login :: Text,
      avatar_url :: Text,
      events_url :: URL,
      followers_url :: URL,
      following_url :: URL,
      gists_url :: URL,
      html_url :: URL,
      organizations_url :: URL,
      received_events_url :: URL,
      repos_url :: URL,
      starred_url :: URL,
      subscriptions_url :: URL,
      url :: URL,
      owner_type :: Text,
      site_admin :: Bool
  } deriving (Show)

$(deriveJSON defaultOptions {fieldLabelModifier = \x -> if x == "owner_type" then "type" else x} ''Owner)

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

_(アンダースコア)は予約済みのキーワードです

分類Dev

JIRAクエリで予約済みのJQLキーワードを使用して修正する最良の方法は?

分類Dev

dynamodbクエリで予約済みキーワード「year」を使用する方法

分類Dev

キーワード「private」は予約済みです(35:12)このファイルタイプを処理するには適切なローダーが必要な場合があります

分類Dev

予約済みのキーワードであるテーブルの列名を返しますか?

分類Dev

Android SQLite JOINクエリで予約済みキーワードを使用する方法は?

分類Dev

古いCコードとその中の予約済みキーワードをC ++でリンクするにはどうすればよいですか?

分類Dev

Luaの予約済みキーワードをすべて印刷する

分類Dev

コールバックでawaitを使用-キーワード「await」は予約済み

分類Dev

JPQLのエンティティ名である予約済みキーワードをエスケープする方法-Hibernate

分類Dev

Ksqlで予約済みのキーワードを「登録」していますか?その場合、その名前のフィールドを選択するにはどうすればよいですか?

分類Dev

Spark SQL / Hive QLで、予約済みキーワードである列を選択する方法

分類Dev

Yahoo YQL API-名前が予約済みのYQLキーワードであるJSONフィールドを選択するにはどうすればよいですか?

分類Dev

SAS ProcSQLの予約済みフィールド名「user」に関する問題

分類Dev

文字「A」はOracleデータベースで予約済みのキーワードですか。

分類Dev

HSQLDB-既存のスキーマで予約済みのSQLキーワードを確認します

分類Dev

ケースクラスフィールドがバッククォート付きの予約済みJavaキーワードである場合、spark-submitは失敗します

分類Dev

モデルで変数名として使用される予約済みキーワードのエスケープ

分類Dev

JavaScriptの予約済みキーワード

分類Dev

NS_SWIFT_NAMEで予約済みのキーワードを使用できますか?

分類Dev

ASP.NET MVC4 ...「BIN」は予約済みのキーワードですか?

分類Dev

VSCodeでJavaScriptの予約済みキーワードをイタリック体にします

分類Dev

Xstreamと、予約済みキーワードをXML属性として使用するための回避策。("クラス")

分類Dev

予約済みの名前golangを持つ構造体フィールド

分類Dev

Mongodbの「未定義」フィールドを処理する方法は?

分類Dev

pywin32でVBAのキーワード引数を処理する方法は?

分類Dev

Emberjsは予約済みのURL文字をエンコードします

分類Dev

ルーターの予約済みIPアドレスをすべて取得する

分類Dev

nHibernate 4.1.4は、予約済みキーワードに一致するテーブル名を引用していません

Related 関連記事

  1. 1

    _(アンダースコア)は予約済みのキーワードです

  2. 2

    JIRAクエリで予約済みのJQLキーワードを使用して修正する最良の方法は?

  3. 3

    dynamodbクエリで予約済みキーワード「year」を使用する方法

  4. 4

    キーワード「private」は予約済みです(35:12)このファイルタイプを処理するには適切なローダーが必要な場合があります

  5. 5

    予約済みのキーワードであるテーブルの列名を返しますか?

  6. 6

    Android SQLite JOINクエリで予約済みキーワードを使用する方法は?

  7. 7

    古いCコードとその中の予約済みキーワードをC ++でリンクするにはどうすればよいですか?

  8. 8

    Luaの予約済みキーワードをすべて印刷する

  9. 9

    コールバックでawaitを使用-キーワード「await」は予約済み

  10. 10

    JPQLのエンティティ名である予約済みキーワードをエスケープする方法-Hibernate

  11. 11

    Ksqlで予約済みのキーワードを「登録」していますか?その場合、その名前のフィールドを選択するにはどうすればよいですか?

  12. 12

    Spark SQL / Hive QLで、予約済みキーワードである列を選択する方法

  13. 13

    Yahoo YQL API-名前が予約済みのYQLキーワードであるJSONフィールドを選択するにはどうすればよいですか?

  14. 14

    SAS ProcSQLの予約済みフィールド名「user」に関する問題

  15. 15

    文字「A」はOracleデータベースで予約済みのキーワードですか。

  16. 16

    HSQLDB-既存のスキーマで予約済みのSQLキーワードを確認します

  17. 17

    ケースクラスフィールドがバッククォート付きの予約済みJavaキーワードである場合、spark-submitは失敗します

  18. 18

    モデルで変数名として使用される予約済みキーワードのエスケープ

  19. 19

    JavaScriptの予約済みキーワード

  20. 20

    NS_SWIFT_NAMEで予約済みのキーワードを使用できますか?

  21. 21

    ASP.NET MVC4 ...「BIN」は予約済みのキーワードですか?

  22. 22

    VSCodeでJavaScriptの予約済みキーワードをイタリック体にします

  23. 23

    Xstreamと、予約済みキーワードをXML属性として使用するための回避策。("クラス")

  24. 24

    予約済みの名前golangを持つ構造体フィールド

  25. 25

    Mongodbの「未定義」フィールドを処理する方法は?

  26. 26

    pywin32でVBAのキーワード引数を処理する方法は?

  27. 27

    Emberjsは予約済みのURL文字をエンコードします

  28. 28

    ルーターの予約済みIPアドレスをすべて取得する

  29. 29

    nHibernate 4.1.4は、予約済みキーワードに一致するテーブル名を引用していません

ホットタグ

アーカイブ