如何用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),所以出现类型不匹配错误。
正确解决步骤
导入必要模块
确保引入处理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字符串转惰性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解码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
相关产品推荐
相关产品推荐

