M.Map внезапно ожидаемая ошибка типа

Все работало отлично примерно до месяца или около того назад...

Вдруг я получаю

 berkson.github.io/source/blog.hs: 333, 42
 • Couldn't match type ‘unordered-containers-0.2.7.1:Data.HashMap.Base.HashMap
                          text-1.2.2.1:Data.Text.Internal.Text
                          aeson-0.11.2.0:Data.Aeson.Types.Internal.Value’
                  with ‘M.Map [Char] [Char]’
   Expected type: M.Map [Char] [Char]
     Actual type: Metadata
 • In the first argument of ‘(M.!)’, namely ‘md’
   In the first argument of ‘(++)’, namely ‘(md M.! "author")’
   In the second argument of ‘(++)’, namely ‘(md M.! "author") ++ "/"’

Из кода:

 directorizeDateAndAuthor :: Routes
 directorizeDateAndAuthor = metadataRoute $ \md ->
     gsubRoute "/[0-9]{4}-[0-9]{2}-[0-9]{2}-" $ \s ->
         replaceAll "-" (const "/") s ++ (md M.! "author") ++ "/"

Мне было интересно, не могли бы вы помочь мне расшифровать, что именно это говорит мне? Я понял, что на моем конце есть какая-то синтаксическая ошибка, но я не понимаю, что изменилось и почему он не компилируется, как раньше?

Ссылка: https://github.com/berkson/berkson.github.io/blob/source/source/blog.hs#L330

1 ответ

Решение

До хакилл 4.8 Metadata Тип синонима был определен следующим образом:

type Metadata = HashMap.Map String String

Метаданные представляли собой простой список пар ключ-значение.

В hakyll 4.8 синтаксический анализ метаданных был изменен ( выпуск, фиксация, объявление о выпуске), чтобы использовать синтаксический анализатор YAML, чтобы позволить более сложную структуру метаданных. Теперь синоним типа следующий:

type Metadata = Aeson.Object

Это Object от aeson пакет - Data.Yaml Библиотека разделяет типы.

К сожалению, обработка Aeson.Object не так просто, как Map было. Чтобы узнать, как правильно использовать Aeson, вы можете прочитать длинный учебник.

К счастью, Джаспер предоставил нам функцию lookupString которая является почти полной заменой HashMap.!:

(!) :: Metadata -> String -> String
lookupString :: String -> Metadata -> Maybe String

Развернув значение Maybe, вы получите что-то вроде следующего кода:

directorizeDateAndAuthor :: Routes
directorizeDateAndAuthor = metadataRoute $ \md ->
  case lookupString "author" md of
      Just author ->
          gsubRoute "/[0-9]{4}-[0-9]{2}-[0-9]{2}-" $ \s ->
              replaceAll "-" (const "/") s ++ author ++ "/"
      Nothing -> error "The author metadata field is missing."
Другие вопросы по тегам