Aeson和镜头有错误处理

 卖火柴的冰枫_939 发布于 2023-01-06 10:30

我对镜头的魔力很新,所以我遇到了一些麻烦.

参考:https://www.fpcomplete.com/user/tel/lens-aeson-traversals-prisms

可以通过以下方式遍历JSON对象:

val ^? nth 0 . key "someObject" . key "version" . nth 2

对于类似于的JSON对象:

"[{\"someObject\": {\"version\": [1, 0, 3]}}]"

Maybe Monad在整个过程中使用,所以如果任何"访问者"失败,我会得到一个Nothing.

我也想传播失败,以便我知道访问者失败了.

我能想到的唯一方法就是传递一组访问器,按顺序应用它们,并在任何失败点返回错误.像这样的东西:

import Data.Aeson
import Data.Text
import Data.Vector ((!?))
import qualified Data.HashMap.Strict  as HM

data MyAccessor = Nth Int | Key Text 

withFailure :: Value -> [MyAccessor] -> Either String Value
withFailure val [] =  Right val 
withFailure val (x:xs) = case x of
    Nth i -> case val of        
        (Array val') -> case (val' !? i) of
            Just e -> withFailure e xs
            _ -> Left $ "Could not get index " ++ (show i)
        _ -> Left $ "Expected JSON array for index " ++ (show i)
    Key k -> case val of  
        (Object val') -> case (HM.lookup k val') of
            Just e -> withFailure e xs
            _ -> Left $ "Could not get key " ++ (unpack k)
        _ -> Left $ "Expected JSON object for key " ++ (unpack k)

所以这个:

-- val =  [[1,0,3], {"name" : "value"}]

> withFailure val [Nth 1, Key "name", Key "hello"]
Left "Expected JSON object for key hello"

> withFailure val [Nth 1, Key "name"]
Right (String "value")

有更优雅的方式吗?制作一个Either-ish monad供镜头使用,结果就像是什么withFailure

撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有