我正在学习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
任何暗示要概括它?
答案 0 :(得分:1)
就像源代码文本[1]
表示具有单个元素(值1
)的列表一样,源代码文本[a]
表示具有单个元素的列表,即变量a
1 。它不表示任何大小的列表,a
表示列表的单个元素,而不是列表。
在等式的左侧,[a]
将是仅匹配包含恰好一个元素(不是零,而不是2或3或更多)的列表的模式;该单个元素的值可以通过等式右边的a
来引用。
所以这段代码:
foo ([a],[b],[c],[d]) = concat [[a],[b]]
给出了将foo
应用于4个单例列表元组的结果的定义。它需要前两个列表中的单个元素(a
和b
),将它们包装在新的单例列表中([a]
和[b]
),将这两个列表放入另一个列表,用于列出列表([[a],[b]]
),然后将该列表传递给函数(concat [[a],[b]]
)。
如果任何一个列表中有多个元素,或者为空,那么这个等式并没有说明foo
的结果是什么。如果没有其他方程式帮助定义函数foo
,那么如果在这种不符合要求的输入上调用foo
,则会出现模式匹配错误。
如果(我怀疑)你想要的是说这个定义适用于任何 4列表的元组,那么你会这样写:
foo (a,b,c,d) = concat [a,b]
请注意a
,b
,c
和d
周围缺少方括号。此版本采用前两个列表(a
和b
)的完整,将这些列表放在另一个列表中以制作列表列表([a,b]
),然后将该列表传递给函数(concat [a,b]
)。
函数的类型(无论是从您的代码中推断出来还是由您声明)表示foo
作为参数接收的元组中的内容是列表 2 ;你不必在列表的每个变量周围加上方括号 - 事实上你不能,因为这意味着其他非常具体的东西!如果要匹配任何可能的列表,只需编写a
;写[a]
表示列表必须是一个元素的列表,并且它只是由变量a
自由匹配的元素,而不是列表本身。
每次使用方括号语法时,您都会编写一个包含固定数量元素的列表, 3 ,括号中的内容是列表中的各个元素。
1 在[a]
是值表达式的上下文中。如果在类型表达式中出现这种情况,则[a]
是列表的类型,其元素为类型 a
。
2 从技术上讲,如果您在此处使用推断类型,那么在我建议的版本中根本不会限制c
和d
的类型,因为它们未被使用,所以他们不必是名单。
3 除非您正在编写列表推导(例如[x + 1 | x <- [1, 2, 3]]
)或数字范围表达式(例如[1..n]
)。
答案 1 :(得分: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]