为什么这个定义不涵盖所有模式案例?

时间:2015-09-11 21:52:04

标签: haskell non-exhaustive-patterns

所以我试图triplize一个元素,即制作另外两个元素的副本。

所以我写了这个:

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

但是我收到了这个错误:

Non-exhaustive patterns in function triplize

我是Haskell的新手,所以任何指针都会受到赞赏!

3 个答案:

答案 0 :(得分:7)

写作时

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])。

答案 1 :(得分:3)

您可以将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

答案 2 :(得分:0)

[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