我经常有一个"也许没有someFunc"模式的代码:
instance FromJSON SaveSection where
parseJSON (Object o) =
SaveSection <$>
o .:? "eventId" <*>
(maybe Nothing parseUSDate <$> o .:? "eventDate") <*>
o .:? "eventRecId" <*>
o .:? "idxId" <*>
(maybe Nothing parseUSDate <$> o .:? "idxDate") <*>
o .:? "idxRecId"
Run Code Online (Sandbox Code Playgroud)
这里parseUSDate有类型Text -> Maybe Date.
Aeson解析显然会返回Maybe Text.
所以在我看来,我需要在Maybe这里提升2层.我不知道如何以任何其他方式做到这一点,但有maybe Nothing someFunc模式.
我错过了一些明显的"扁平化"或者我可以在这里使用的任何功能吗?
编辑:感谢Alexey的回答.
这正是我想要的.这是最终结果:
instance FromJSON SaveSection where
parseJSON (Object o) =
SaveSection <$>
o .:? "eventId" <*>
((>>= parseUSDate) <$> o .:? "eventDate") <*>
o .:? "eventRecId" <*>
o .:? "idxId" <*>
((>>= parseUSDate) <$> o .:? "idxDate") <*>
o .:? "idxRecId"
Run Code Online (Sandbox Code Playgroud)
bhe*_*ilr 10
有一个非常方便的Control.Monad.join功能:
> join (Just (Just 1))
Just 1
> join (Just Nothing)
Nothing
> join Nothing
Nothing
Run Code Online (Sandbox Code Playgroud)
我不是艾森的专家,但如果我这样做:
> :m Control.Monad Control.Applicative Data.Aeson Data.Text
> :set -XOverloadedStrings
> :set +m
> let f :: Text -> Maybe Text
| f = Just -- Stand-in for parseUSDate
> :t \o -> join <$> liftM f <$> o .:? "key"
Object -> Parser (Maybe Text)
> -- Has the same type as your expression
> :t \o -> maybe Nothing f <$> o .:? "key"
Object -> Parser (Maybe Text)
Run Code Online (Sandbox Code Playgroud)
这是你要找的东西吗?
编辑:修复,以便它实际上工作...我的初始通用f :: a -> Maybe a是弄乱的东西.
您可以让操作员清理它:
infixl 9
(>>=$) :: (Functor f, Monad m) => f (m a) -> (a -> m b) -> f (m b)
m >>=$ a = join <$> liftM a <$> m
parseJSON (Object o) =
SaveSection
<$> o .:? "eventId"
<*> o .:? "eventDate" >>=$ parseUSDate
<*> o .:? "eventRecId"
<*> o .:? "idxId"
<*> o .:? "idxDate" >>=$ parseUSDate
<*> o .:? "idxRecId"
Run Code Online (Sandbox Code Playgroud)
(这应该工作......)