干净地访问 lens-aeson 中的嵌套数据
Cleanly accessing nested data in lens-aeson
我有以下代码,但我对它不满意:
import Data.Aeson.Lens
import Data.Aeson.Types
import Data.Text hiding (foldl, map)</p>
<p>path :: (Applicative f, AsValue t) => [Text] -> (Value -> f Value) -> t -> f t
path [] = error "No path provided"
path (i:is) = foldl (.) (key i) (map key is)
</pre>
path
是嵌套 JSON 对象的镜头。例如:
"{ \"a\": { \"b\": 8} }" ^? path ["a", "b"] == Just (Number 8.0)
目前可以用,但有点明显的缺点是功能不全
我尝试了以下定义:
path is = foldl (.) id (map key is)
path [] = id
path (i:is) = foldl (.) (key i) (map key is)
-- This one doesn't compile
path [] = _Object
path (i:is) = foldl (.) (key i) (map key is)
运行 与上述定义相同的代码块产生 Nothing
,而不是预期的 8
.
我几乎可以肯定这是我所缺少的类型杂耍的情况,但我无法弄清楚如何使它与总功能一起工作。 path []
的预期行为是一个 Lens
,它专注于整个 json 对象。
对空的情况使用_Value
:
> ("null" :: String) ^? _Value
Just Null
> ("null" :: String) ^? (foldl (.) _Value $ map key ["foo", "bar"])
Nothing
> ("{ \"a\": { \"b\": 8} }" :: String) ^? (foldl (.) _Value $ map key ["a", "b"])
Just (Number 8.0)
另外,您描述的 path
不能是 Lens
,因为它是部分的(正如您提到的!),充其量是 Traversal
。然而,如果您真的确定自己在做什么,那么您可以使用 signular
将 Traversal
转换为 Lens
。
我有以下代码,但我对它不满意:
import Data.Aeson.Lens import Data.Aeson.Types import Data.Text hiding (foldl, map)</p> <p>path :: (Applicative f, AsValue t) => [Text] -> (Value -> f Value) -> t -> f t path [] = error "No path provided" path (i:is) = foldl (.) (key i) (map key is) </pre>
path
是嵌套 JSON 对象的镜头。例如:"{ \"a\": { \"b\": 8} }" ^? path ["a", "b"] == Just (Number 8.0)
目前可以用,但有点明显的缺点是功能不全
我尝试了以下定义:
path is = foldl (.) id (map key is)
path [] = id path (i:is) = foldl (.) (key i) (map key is)
-- This one doesn't compile path [] = _Object path (i:is) = foldl (.) (key i) (map key is)
运行 与上述定义相同的代码块产生
Nothing
,而不是预期的8
.我几乎可以肯定这是我所缺少的类型杂耍的情况,但我无法弄清楚如何使它与总功能一起工作。
path []
的预期行为是一个Lens
,它专注于整个 json 对象。
对空的情况使用_Value
:
> ("null" :: String) ^? _Value
Just Null
> ("null" :: String) ^? (foldl (.) _Value $ map key ["foo", "bar"])
Nothing
> ("{ \"a\": { \"b\": 8} }" :: String) ^? (foldl (.) _Value $ map key ["a", "b"])
Just (Number 8.0)
另外,您描述的 path
不能是 Lens
,因为它是部分的(正如您提到的!),充其量是 Traversal
。然而,如果您真的确定自己在做什么,那么您可以使用 signular
将 Traversal
转换为 Lens
。