【问题标题】:haskell : good usage of map, number of arguments [duplicate]haskell:地图的良好用法,参数数量[重复]
【发布时间】:2015-10-06 16:01:44
【问题描述】:

map 的签名是(a -> b) -> [a] -> [b],这意味着它接受 2 个参数并返回一个列表。 然而,以下将字符串转换为首字母大写克隆的函数是错误的:

modernise :: String -> String
modernise s = unwords . map (\m -> [toUpper (head m)] ++ tail m) (words s)

好的版本是:

modernise :: String -> String
modernise = unwords . map (\m -> [toUpper (head m)] ++ tail m) . words

第一个版本被拒绝,错误提示:"too many arguments for the map function";但我给出了 2 个参数(lambda 函数和 words 的结果),这是很好的参数数量。

你能帮帮我吗?

【问题讨论】:

  • 我更喜欢 map (\(x:xs) -> toUpper x : xs) 的地图功能。一般来说,没有理由更喜欢[x] ++ xs 而不是x : xs,而且模式匹配几乎总是应该优先于头部和尾部。
  • @ReinHenrichs,确实如此,不幸的是,words 返回的是列表列表而不是 NonEmptys 列表。
  • 后人快速说明:我将其作为问题 X 的副本关闭,它是 Y 的副本。但是,我认为 X 和 Y 之间存在一些细微的差异,这使得这个问题不是Y的副本;但是 X 处的答案确实解决了这个问题引起的混乱。 (可能 X 首先不应该是 Y 的副本,尽管我可以理解为什么它会以这种方式关闭。)

标签: haskell


【解决方案1】:

在第一个版本中,你写了

modernise s = unwords . map whatever (words s)

根据.的定义,这意味着

modernise s = \x -> unwords (map whatever (words s) x)

您可以改用$ 运算符:

modernise s = unwords $ map whatever (words s)

但是你要工作的版本是完全地道和清晰的,所以没有必要改变它的结构。

【讨论】:

  • 这是一个经常犯的错误,我想知道为什么 GHC 没有为新用户检测其背后的意图并报告更易于理解的错误消息。
  • @ErikAllik,让类型检查器提供可用的错误消息已经够难的了,而无需尝试了解常见的混淆函数。此外,类型检查器不回溯,并且为了速度,使用不支持回溯的技术来实现。所以它实际上并没有能力假设性地尝试使用替代功能;一旦看到.,它就会提交给它。
【解决方案2】:

您想要application operator ($) :: (a -> b) -> a -> b 而不是函数组合(.) :: (b -> c) -> (a -> b) -> a -> c 的点。

modernise s = unwords $ map (\m -> [toUpper (head m)]  ++ tail m) (words s)

相同
modernise s = unwords ( map (\m -> [toUpper (head m)]  ++ tail m) (words s) )

【讨论】:

    【解决方案3】:

    "map 函数的参数太多";但我给出了 2 个参数(lambda 函数和“单词”的结果),这是很好的参数数量。

    没错。在子表达式 map (\m -> [toUpper (head m)] ++ tail m) (words s) 中,您给了 map 两个参数,并得到了 [String] 类型的值,这是一个非函数类型。但是,您将结果视为函数,因为(.) 的第二个参数必须是函数类型。

    每当您尝试在需要函数的地方提供非函数值时,编译器都会提供诊断。有问题的子表达式是函数map 的多重应用,这就是为什么编译器会建议您可能尝试向它提供太多参数。

    正如其他人已经说过的,您需要($) 函数。

    【讨论】:

      猜你喜欢
      • 2016-07-17
      • 1970-01-01
      • 2011-05-12
      • 1970-01-01
      • 2011-10-27
      • 2011-09-28
      • 2015-02-07
      • 2010-12-31
      • 1970-01-01
      相关资源
      最近更新 更多