Haskell初学者在这里。我想用JSON传递一个“type”参数,并使用read解析为本机Haskell类型。以下作品:
data CreatureType = Bot | Player deriving (Generic, Typeable, Show, Read)
data Creature = Creature CreatureType deriving (Typeable, Show)
instance FromJSON Creature where
parseJSON (A.Object v) = Creature <$> read <$> (v .: "type")
parseJSON _ = mzero
我想将其更改为与readMay
一起使用,以便在读取失败时不会崩溃。我一直卡住了。如果mzero
返回readMay
,则parseJSON需要返回Nothing
。
主要问题:如何让这个函数使用readMay
在读取失败时返回mzero
?
这是我尝试过的:
instance FromJSON Creature where
parseJSON (A.Object v) = do
let t = (v .: "type") :: Parser String
mt = readMay <$> t :: Parser (Maybe CreatureType)
-- ??
-- guard -- I can't use this because it wants a Bool, and I only have Parser Bool
-- Creature <$> read <$> mt
parseJSON _ = mzero
mt
是Parser (Maybe CreatureType)
。如果是Nothing
,我如何更改我返回的内容?我不能使用模式匹配,因为Data.Aeson
似乎没有为Parser导出值构造函数。我似乎找不到任何方法可以在解析器中提供值,因此,是否有一个通用的haskell方法可以做到这一点?我看了Control.Applicative
但找不到任何东西。以下是Data.Aeson
的文档。 http://hackage.haskell.org/packages/archive/aeson/0.5.0.0/doc/html/Data-Aeson.html
答案 0 :(得分:1)
不会在do-block工作中绑定值吗?
maybeCreature <- mt
case maybeCreature of
Nothing -> mzero
Just cr -> return (Creature cr)
或类似的?
instance FromJSON Creature where
parseJSON (A.Object v) = do
let t = (v .: "type") :: Parser String
mt = readMay <$> t :: Parser (Maybe CreatureType)
maybeCreature <- mt
-- variant 1, guard
guard (isJust maybeCreature)
return (Creature $ fromJust maybeCreature)
-- variant 2, fromMaybe
fromMaybe mzero (return . Creature) maybeCreature
-- variant 3, case, see above
parseJSON _ = mzero