【问题标题】:Why doesn't this definition cover all pattern cases?为什么这个定义不涵盖所有模式案例?
【发布时间】:2015-09-11 21:52:03
【问题描述】:

所以我正在尝试 triplize 一个元素,即制作该元素的另外 2 个副本。

所以我写了这个:

triplize :: [a] -> [a]
triplize [x] = concatMap (replicate 3) [x]

但我一直收到此错误:

Non-exhaustive patterns in function triplize

我是 Haskell 的新手,请大家多多指教!

【问题讨论】:

  • 列表为空时怎么办。你没抓住那个案子?
  • 不需要考虑这个:)
  • @NeedHelp 是的。 triplize [] = [],根据您的定义。不完整的功能被认为是有害的。

标签: haskell non-exhaustive-patterns


【解决方案1】:

当你写作时

triplize [x]

您是说参数必须与模式[x] 匹配。此模式表示具有单个值的列表,该值将分配给名称x。请注意,该列表不会分配给名称x,只会分配给该列表中的单个值。如果您尝试使用列表 [][1, 2] 调用您的函数,则会导致错误,因为您没有告诉您的函数如何处理这些输入。

你可能想要的是

triplize x = concatMap (replicate 3) x

这里你的模式只是x,它匹配任何列表,从空列表到无限列表。请注意,函数定义中的模式与您自己创建值的方式相匹配。在 Haskell 中,您可以对构造函数进行模式匹配,并且可以使用方括号和逗号构造列表,或者可以使用 : 运算符构造列表,例如 [1, 2, 3] == (1:2:3:[])。事实上,: 运算符是 Haskell 内部表示列表的方式。

使用更多模式匹配的示例:

sumSuccessive :: [Int] -> [Int]
sumSuccessive [] = []      -- Empty list
sumSuccessive [x] = [x]    -- Singleton list (only one value)
sumSuccessive (x:y:rest) = x + y : sumSuccessive rest
    -- Match a list with at least two elements `x` and `y`,
    -- with the rest of the list assigned to the name `rest`

此示例函数将获取列表 [1, 2, 3, 4] 并返回列表 [3, 7] ([1 + 2, 3 + 4])。

【讨论】:

  • 一个常见的命名参数的习惯用法是使用xs 或类似的列表名称。例如。 triplize xs = concatMap (replicate 3) xs
【解决方案2】:

您可以将triplize 定义为:

triplize :: [a] -> [a]
triplize x = concatMap (replicate 3) x

但是甚至不用写x

triplize :: [a] -> [a]
triplize = concatMap (replicate 3)

原始代码仅适用于具有一个元素的列表:

> triplize [1]
[1, 1, 1]
> triplize []
*** Exception: Non-exhaustive patterns in function triplize
> triplize [0, 1]
*** Exception: Non-exhaustive patterns in function triplize

【讨论】:

    【解决方案3】:

    [x] 匹配仅包含一个元素的列表。如果要匹配任何列表,只需删除 []

    triplize x = concatMap (replicate 3) x
    

    这会将["a", "b", "c"] 变成["a", "a", "a", "b", "b", "b", "c", "c", "c"]

    另一方面,如果您想获取一个元素并返回一个列表(包含该元素的 3 个),那么您的代码应该是

    triplize :: a -> [a]
    triplize x = replicate 3 x
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-05-25
      • 2021-12-07
      • 1970-01-01
      • 2016-09-05
      • 2020-09-13
      • 1970-01-01
      • 2011-02-09
      • 2014-04-14
      相关资源
      最近更新 更多