Haskell 在Aeson解析器中展平MonadPlus
我不确定我是不是找错了方向,但我有一个Aeson-FromJSON定义,它看起来相当庞大,我想知道它是否可以变得更简洁。如果URI的嵌套解析失败,我想缩短整个对象的解析Haskell 在Aeson解析器中展平MonadPlus,haskell,composition,aeson,monadplus,Haskell,Composition,Aeson,Monadplus,我不确定我是不是找错了方向,但我有一个Aeson-FromJSON定义,它看起来相当庞大,我想知道它是否可以变得更简洁。如果URI的嵌套解析失败,我想缩短整个对象的解析 data Link = Link { link :: URI , tags :: [String] } deriving (Show, Typeable, Eq) instance FromJSON Link where parseJSON :: Va
data Link = Link { link :: URI
, tags :: [String]
} deriving (Show, Typeable, Eq)
instance FromJSON Link where
parseJSON :: Value -> Parser Link
parseJSON (Object o) = do
linkStr <- o .: "link"
tags' <- o .: "tags"
case parseURI linkStr of
Just l -> return $ Link l tags'
Nothing -> mzero
parseJSON _ = mzero
parseURI的类型是parseURI::String->Maybe URI,Maybe和Parser都有MonadPlus实例。有没有一种方法可以直接组合这两个元素,并在最后删除丑陋的case语句?解析器通常更简洁,您可以使用mzero返回将Nothing转换为mzero来组合parseURI的结果
解析器通常更简洁,您可以使用mzero返回将Nothing转换为mzero来合成parseURI的结果
模式匹配可以工作,但这只在do not explicit>>=内部工作,因为会进行额外的去糖化:
instance FromJSON Link where
parseJSON (Object o) = do
Just link' <- o .: "link"
tags' <- o .: "tags"
return $ Link link' tags'
parseJSON _ = mzero
这里发生的情况是,模式匹配左侧的失败模式匹配起作用,但这只在do not explicit>>=内部起作用,这是由于额外的去糖化:
instance FromJSON Link where
parseJSON (Object o) = do
Just link' <- o .: "link"
tags' <- o .: "tags"
return $ Link link' tags'
parseJSON _ = mzero
这里发生的事情是,在a的左手边,一个失败的模式匹配,哦,我在一次尝试中非常接近。谢谢,这正是我想要的解决方案!哦,在我的一次尝试中,我是如此接近。谢谢,这正是我想要的解决方案!
> -- Note that I used link :: String for my testing instead
> decode "{\"link\": \"test\", \"tags\": []}" :: Maybe Link
Just (Link {link = "test", tags=[]})
> decode "{\"tags\": []}" :: Maybe Link
Nothing