【问题标题】:M.Map sudden expected type errorM.Map 突然出现预期类型错误
【发布时间】:2016-06-14 00:12:58
【问题描述】:

直到大约一个月前,一切都很好......

突然之间,我得到了

 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

【问题讨论】:

  • 我的猜测是您升级了定义Metadata 的包,并且该包从定义它的Map 更改为HashMap。您需要更新此类型的用法以使用例如HashMap.! 而不是 M.!。或者您可以更改您的 cabal 文件以依赖旧版本的软件包。
  • 在 hakyll 4.8 Metadata 中,类型从 Map 更改为 Aeson.Object(参见 release announcement
  • @JanTojnar 嘎!谢谢你告诉我,但现在我更迷茫了!我认为这只是自己的替代品,而不是在我得到之前的错误:Couldn't match expected type ‘[Char]’ with actual type ‘Value’ 相反! >_

标签: haskell hakyll overloaded-strings unordered-containers


【解决方案1】:

在 hakyll 4.8 之前,Metadata 类型的同义词定义如下:

type Metadata = HashMap.Map String String

元数据只是键-值对的平面列表。

在 hakyll 4.8 中,元数据解析已更改(issuecommitrelease anouncement)以使用 YAML 解析器,以允许更复杂的元数据结构。现在,类型同义词如下:

type Metadata = Aeson.Object

这是来自aeson 包的Object - Data.Yaml 库共享类型。

不幸的是,处理Aeson.Object 并不像Map 那样简单。要了解如何正确使用 Aeson,可以阅读lengthy tutorial

幸运的是,Jasper 为我们提供了一个函数 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."

【讨论】:

    猜你喜欢
    • 2021-11-14
    • 1970-01-01
    • 2022-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多