Что Мзеро в этом примере Эзона? - PullRequest
2 голосов
/ 12 апреля 2019

Я видел этот вопрос на SO и пытаюсь его воспроизвести: Haskell: повторное использование экземпляров FromJSON с линзами, линз-эзоном и вложенным 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 Ответ

3 голосов
/ 12 апреля 2019

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 == x и mplux 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 означает, чтоникакое значение JSON, кроме String, не может быть интерпретировано как кодирование значения Colour.

...