You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Haskell中获取数据类型对应对象键名的最优实现方法是什么?

方案1:保留aeson依赖,去掉多余的编解码往返

你原本的实现需要先把对象序列化为JSON字节串再反序列化为Object,属于无意义的往返操作,既增加了性能开销,还引入了不必要的解码失败分支。直接调用toJSON方法就能拿到JSON结构,匹配出Object后直接取键即可:

{-# LANGUAGE DeriveGeneric #-}

import Data.Aeson
import GHC.Generics
import qualified Data.HashMap.Strict as HashMap

data Person = Person {
    name :: String,
    age :: Int
} deriving (Generic, Show)

instance ToJSON Person

main :: IO ()
main = do
    let p = Person "random" 100
    case toJSON p of
        Object obj -> print $ HashMap.keys obj
        -- 对普通记录类型派生的ToJSON实例,下方分支永远不会触发
        _ -> print "unexpected JSON type"

运行输出和你原实现一致:["age","name"]


方案2:不需要aeson依赖,直接取Haskell记录字段名

如果你只需要获取记录类型本身定义的字段名,不需要和aeson的序列化逻辑绑定,可以直接用base库自带的Data.Data泛型能力实现,完全不需要引入第三方依赖,性能开销最低:

{-# LANGUAGE DeriveDataTypeable #-}

import Data.Data (Data, toConstr, constrFields)

data Person = Person {
    name :: String,
    age :: Int
} deriving (Data, Show)

main :: IO ()
main = print $ constrFields $ toConstr $ Person undefined undefined

运行输出为["name","age"],顺序和你定义记录字段的顺序完全一致,如果需要和aeson输出的排序保持一致,自行做排序处理即可。

内容的提问来源于stack exchange,提问作者vijaicv

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 10:36:05