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

使用Haskell Aeson库解析指定格式JSON数据源的技术问询

Parsing Your JSON Field Structure with Haskell's Aeson Library

Hey there! Let's break down exactly how to parse that JSON structure you've got using Aeson, Haskell's go-to library for JSON handling. We'll go from defining types to writing parsing logic, with full code examples to make it concrete.


1. Define Haskell Types to Match the JSON Structure

First, we need to map your JSON's structure to type-safe Haskell types. Your JSON has a top-level object with a fields array; each array element has three properties: type, name, and description.

We'll use an enum for the type field (instead of raw strings) to keep our code type-safe, and define nested types for individual fields and the full collection.

{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}

import Data.Aeson
import Data.Text (Text)
import GHC.Generics
import Data.ByteString.Char8 (ByteString)

-- Enum for the field types in your JSON (matches "datetime" and "number")
data FieldType = DateTimeType | NumberType
  deriving (Show, Eq, Generic)

-- Represents a single field entry from the JSON
data Field = Field
  { fieldType :: FieldType
  , fieldName :: Text
  , fieldDescription :: Text
  } deriving (Show, Eq, Generic)

-- Top-level type for the entire JSON structure
data FieldCollection = FieldCollection
  { fields :: [Field]
  } deriving (Show, Eq, Generic)

2. Write FromJSON Instances

Next, we need to tell Aeson how to convert JSON values into our Haskell types. We'll write a custom instance for FieldType to map the JSON strings to our enum constructors, and a manual instance for Field to correctly map JSON keys to our Haskell field names.

-- Custom parser for FieldType: maps JSON strings to our enum
instance FromJSON FieldType where
  parseJSON = withText "FieldType" $ \t ->
    case t of
      "datetime" -> pure DateTimeType
      "number" -> pure NumberType
      _ -> fail $ "Unrecognized field type: " ++ show t

-- Manual parser for Field: explicitly maps JSON keys to Haskell fields
instance FromJSON Field where
  parseJSON = withObject "Field" $ \obj ->
    Field
      <$> obj .: "type"         -- Map JSON "type" to fieldType
      <*> obj .: "name"         -- Map JSON "name" to fieldName
      <*> obj .: "description"  -- Map JSON "description" to fieldDescription

-- Generic parser works here: JSON key "fields" matches our Haskell field name
instance FromJSON FieldCollection

3. Parse Your JSON Data

With our types and parsers set up, we can use Aeson's parsing functions to convert JSON into Haskell values. eitherDecode is ideal here because it returns a human-readable error message if parsing fails.

Example Usage

-- Sample JSON matching your structure
sampleJSON :: ByteString
sampleJSON = "{\"fields\": [ { \"type\": \"datetime\", \"name\": \"Observation Valid\", \"description\": \"Observation Valid Time\"}, { \"type\": \"datetime\", \"name\": \"Observation Valid UTC\", \"description\": \"Observation Valid Time UTC\"}, { \"type\": \"number\", \"name\": \"Air Temperature[F]\", \"description\": \"Air Temperature at 2m AGL\"}, { \"type\": \"number\", \"name\": \"Wind Speed[kt]\", \"description\": \"Wind Speed\"}, { \"type\": \"number\", \"name\": \"Wind Gust[kt]\", \"description\": \"Wind Gust\"} ]}"

-- Parse the sample JSON
parseSample :: Either String FieldCollection
parseSample = eitherDecode sampleJSON

-- Run the parser and handle results
main :: IO ()
main = case parseSample of
  Right collection -> print collection
  Left err -> putStrLn $ "Parsing failed: " ++ err

4. Handling Edge Cases

  • Unknown fields: If your JSON might have extra fields you don't care about, modify the generic parser to allow unknown keys:
    instance FromJSON FieldCollection where
      parseJSON = genericParseJSON defaultOptions { allowUnknownFields = True }
    
  • Additional field types: If you encounter more type values (like "string"), just add a new constructor to FieldType and update the FromJSON instance to handle it.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:18:19