这个aeson例子中的mzero是什么?

问题描述 投票:2回答:1

我在SO上看到了这个问题,并试图复制它:Haskell: Reusing FromJSON instances with lenses, lens-aeson, and nested JSON

但是,当我运行我认为应该是一个完整的例子时,我得到一个错误。

这是我的代码:

import Data.Aeson
import Data.Aeson.Lens
import Control.Lens
import Data.Aeson.Types

data Colour = Yellow | Green | Blue

instance FromJSON Colour where
  parseJSON (String s) = return $ case s of
        "blue" -> Blue
        "green" -> Green
        _ -> Yellow
  parseJSON _ = mzero

instance ToJSON Colour where
  toJSON Yellow = String "yellow"
  toJSON Blue   = String "blue"
  toJSON Green  = String "green"

parseColour :: String -> Maybe Colour
parseColour j = j ^? key "info" . key "colour" . _JSON

parseColour "{ \"info\": { \"colour\": \"yellow\" } }"

我明白了:

 <interactive>:7:17: error: Variable not in scope: mzero :: Parser Colour

很多搜索都成功地显示了这样使用的mzero变量。我不知道它是从包中导入的东西还是只是一个任意的变量名,而且我在滥用这个功能。无论哪种方式,我都不清楚为什么从问题中复制此代码似乎在此失败。

haskell aeson
1个回答
3
投票

mzero是在MonadPlus中定义的Control.Monad类型类的一部分。

> import Control.Monad
> :info MonadPlus
class (GHC.Base.Alternative m, Monad m) =>
      MonadPlus (m :: * -> *) where
  mzero :: m a
  mplus :: m a -> m a -> m a

它作为mplus函数的身份,使mplus mzero x == xmplux x mzero == x

mzeroFromJSON实例中的使用在文档中提到:

在编写实例时,使用empty,mzero或者无法使转换失败,例如如果对象缺少必需的键,或者值的类型错误。

所以在你引用的实例中

instance FromJSON Colour where
  parseJSON (String s) = return $ case s of
        "blue" -> Blue
        "green" -> Green
        _ -> Yellow
  parseJSON _ = mzero

mzero表示除了String之外没有JSON值可以解释为编码Colour值。

© www.soinside.com 2019 - 2024. All rights reserved.