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

如何用Aeson解码含Unicode字符的JSON?解决编译类型不匹配问题

解决Haskell Aeson解码含Unicode JSON的问题

问题根源

初始用C8.pack(Data.ByteString.pack)处理字符串时,它仅支持ASCII编码,会直接破坏Unicode字符(比如中文、特殊符号)的字节结构,导致JSON格式无效,Aeson解码自然返回Nothing。而后续尝试E.encodeUtf8+T.pack时,因为encodeUtf8返回严格ByteString(Data.ByteString.ByteString),但Aeson的decode默认接受惰性ByteString(Data.ByteString.Lazy.ByteString),所以出现类型不匹配错误。

正确解决步骤

  1. 导入必要模块
    确保引入处理Text、ByteString和Aeson的核心模块:

    import Data.Aeson (decode, eitherDecode)
    import Data.Text (Text, pack)
    import Data.Text.Encoding (encodeUtf8)
    import qualified Data.ByteString.Lazy as BL
    
  2. 字符串转惰性ByteString的正确流程
    把普通String转成Aeson能识别的UTF-8编码惰性ByteString:

    -- 示例含Unicode的JSON字符串
    unicodeJsonStr :: String
    unicodeJsonStr = "{\"username\": \"李雷\", \"email\": \"lilei@example.com\"}"
    
    -- 转换:String → Text → 严格ByteString → 惰性ByteString
    lazyUtf8BS :: BL.ByteString
    lazyUtf8BS = BL.fromStrict $ encodeUtf8 $ pack unicodeJsonStr
    
  3. 解码JSON
    用decode返回Maybe类型结果,或用eitherDecode获取详细错误信息(调试时更实用):

    -- 假设你定义了对应的JSON数据类型
    data User = User { username :: Text, email :: Text } deriving (Show, Generic, FromJSON)
    
    -- 用decode获取Maybe结果
    decodedUser :: Maybe User
    decodedUser = decode lazyUtf8BS
    
    -- 用eitherDecode获取错误详情
    decodedUserEither :: Either String User
    decodedUserEither = eitherDecode lazyUtf8BS
    

读取JSON文件的简化方案

如果是从文件读取含Unicode的JSON,直接用BL.readFile读取为惰性ByteString即可,无需手动编码转换:

decodeUnicodeJsonFile :: FilePath -> IO (Maybe User)
decodeUnicodeJsonFile filePath = decode <$> BL.readFile filePath

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 15:13:19