为什么这个定义不涵盖所有模式案例?
Why doesn't this definition cover all pattern cases?
所以我正在尝试 triplize
一个元素,即制作该元素的另外 2 个副本。
所以我写了这个:
triplize :: [a] -> [a]
triplize [x] = concatMap (replicate 3) [x]
但是我一直收到这个错误:
Non-exhaustive patterns in function triplize
我是 Haskell 的新手,非常感谢任何指点!
写的时候
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]
和 return 列表 [3, 7]
([1 + 2, 3 + 4]
).
您可以将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
[x]
匹配恰好包含一个元素的列表。如果你想匹配任何列表,只需删除 [
和 ]
:
triplize x = concatMap (replicate 3) x
这会将 ["a", "b", "c"]
变成 ["a", "a", "a", "b", "b", "b", "c", "c", "c"]
。
另一方面,如果您想获取一个元素和 return 一个列表(包含该元素的 3 个),那么您的代码应该是
triplize :: a -> [a]
triplize x = replicate 3 x
所以我正在尝试 triplize
一个元素,即制作该元素的另外 2 个副本。
所以我写了这个:
triplize :: [a] -> [a]
triplize [x] = concatMap (replicate 3) [x]
但是我一直收到这个错误:
Non-exhaustive patterns in function triplize
我是 Haskell 的新手,非常感谢任何指点!
写的时候
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]
和 return 列表 [3, 7]
([1 + 2, 3 + 4]
).
您可以将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
[x]
匹配恰好包含一个元素的列表。如果你想匹配任何列表,只需删除 [
和 ]
:
triplize x = concatMap (replicate 3) x
这会将 ["a", "b", "c"]
变成 ["a", "a", "a", "b", "b", "b", "c", "c", "c"]
。
另一方面,如果您想获取一个元素和 return 一个列表(包含该元素的 3 个),那么您的代码应该是
triplize :: a -> [a]
triplize x = replicate 3 x