这个aeon示例中的零是什么?

时间:2019-04-12 13:06:30

标签: haskell aeson

我在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变量。我不知道这是从包中导入的东西,还是只是一个任意的变量名,而我滥用了该函数。无论哪种方式,我都不清楚为什么从问题中复制此代码似乎对此失败。

1 个答案:

答案 0 :(得分:3)

mzeroMonadPlus中定义的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

文档中提到在mzero的实例中使用FromJSON

  

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

所以在您引用的实例中

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

mzero表示除String以外的其他JSON值都不能解释为对Colour值进行编码。