0

我正在学习Haskell,这个问题可能很愚蠢,但抱歉我不知道它的答案

我有一个函数,它采用 4 元组列表,这些列表的大小可能不同,但在元组中它们具有相同的大小

foo ([a],[b],[c],[d]) = concat [[a],[b])

例如,它不适用于大于一号的列表

foo ([1],[2],[3],[4]) // works fine 
foo ([1,2] , [2,3] , [3,4] , [5,7]) or any larger size of those list generate error

任何关于概括它的提示?

4

2 回答 2

1

就像源代码文本[1]意味着具有单个元素的列表一样,源代码文本意味着具有单个元素1[a]列表,即变量a1。它并不意味着任何大小a的列表,而是指列表的单个元素,而不是列表。

在等式的左侧,[a]将是一个模式,它只匹配包含恰好一个元素(不是零,也不是 2 或 3 或更多)的列表;该单个元素的值可以a在等式的右侧引用。

所以这段代码:

foo ([a],[b],[c],[d]) = concat [[a],[b]]

给出应用foo到 4 个单例列表的元组的结果的定义。它获取前两个列表(ab)中的单个元素,将它们包装在新的单例列表([a][b])中,将这两个列表放入另一个列表中以创建列表列表([[a],[b]]),然后将该列表传递给函数(concat [[a],[b]])。

如果任何一个列表有多个元素,或者是空的,那么这个等式并没有说明结果foo是什么。如果没有其他方程式可以帮助定义 function foo,那么如果您调用foo此类不符合要求的输入,则会出现模式匹配错误。

如果(我怀疑)你想要说这个定义适用于任何4 个列表的元组,那么你可以这样写:

foo (a,b,c,d) = concat [a,b]

a注意, b,c和周围没有方括号d。此版本获取前两个列表(和)的全部内容,将它们放在另一个列表中以创建列表列表(),然后将该列表传递给函数()。ab[a,b]concat [a,b]

函数的类型(无论是从您的代码推断还是由您声明)表示foo作为参数接收的元组中的事物是列表2;您不必在列表中的每个变量周围加上方括号 - 实际上您不能,因为这意味着其他一些非常具体的东西!当你想匹配任何可能的列表时,你只需写a; 写作[a]说列表必须是一个恰好包含一个元素的列表,并且只有那个元素可以由变量自由匹配a,而不是列表本身。

每当您使用方括号语法时,您都在编写具有固定数量元素的列表,3并且括号中的内容是列表的各个元素。


1[a]值表达式的上下文中。如果这发生在类型表达式中,则它的元素是 type 的[a]列表类型 a

2从技术上讲,如果您在这里使用推断类型,那么在我建议的版本中就没有任何限制cand的类型,d因为它们没有被使用,所以它们不必是列表。

3除非您正在编写列表推导式(例如[x + 1 | x <- [1, 2, 3]])或数字范围表达式(例如[1..n])。

于 2013-10-14T07:15:29.450 回答
0

这应该有效:

foo (a:_,b:_,c:_,d:_)= concat [[a],[b]]

在上面的函数中,您只需模式匹配每个列表参数的第一个元素。

一个更简单的代码:

foo (a:_,b:_,_,_)= [a, b]

在 ghci 中:

ghci> foo ([1],[2],[3],[4])
[1,2]
ghci> foo ([1,2] , [2,3] , [3,4] , [5,7])
[1,2]
于 2013-10-14T05:52:58.243 回答