假设我有一个类似于
的JSON ByteString{
messages: [
{...},
{...}
]
}
我想使用镜头从中获取消息的列表/向量。我有一个函数toMessage
可以将Value
转换为Maybe Message
。
我已尝试过此作文key "messages" . values . to toMessage
(to
来自Control.Lens.Getter
,但结果为Maybe Message
,只是Nothing
。
目前我正在这样做
msgsJson <- c ^? key "messages"
let msgs = toList $ mapMaybe message $ msgsJson ^.. values
(mapMaybe
来自witherable
,toList
是将Vector
转换为列表)
但是我想知道是否有办法组合各种镜头来制作这样的镜头。
答案 0 :(得分:1)
{-# LANGUAGE OverloadedStrings #-}
module Main where
import Data.ByteString (ByteString)
import Control.Lens
import Data.Aeson
import Data.Aeson.Lens
newtype Message =
Message Integer
deriving (Show)
toMessage :: Value -> Maybe Message
toMessage json_ = do
i <- json_ ^? key "a" . _Integer
return (Message i)
input :: ByteString
input = "{\"messages\":[{\"a\":1},{\"a\":2},{\"a\":3}]}"
main :: IO ()
main =
print (input ^.. (key "messages" . values . to toMessage))
λ> main
[Just (Message 1),Just (Message 2),Just (Message 3)]
如果您收到Nothing
,则可能表示您的JSON无效(您可以使用decode json :: Maybe Value
进行测试)。或者组合物中的任何其他光学器件都失效。对于长点缀光学器件,有时很难确切地知道哪一个失效,除非从末端切掉部件并重试。但是你的组合光学key "messages" . values . to toMessage
应该是Just Work™。
顺便说一下:
msgJson <- c ^? key "messages"
let msgs = toList $ mapMaybe message $ msgsJson ^.. values
应与
相同msgJson <- c ^? key "messages"
let msgs = toList $ msgsJson ^.. (values . to message . _Just)
和
msgJson <- c ^? key "messages"
let msgs = msgsJson ^.. (values . to message . _Just)
和
let msgs = c ^.. (key "messages" . values . to message . _Just)