我在haskell中有一个问题,要求一个函数将一个列表分成两个不同的列表,这样偶数索引填充一个列表,奇数索引填充另一个列表。示例:
func :: [Int] -> ([Int], [Int])
字符串
然后,如果我们输入[44,8,11,23],我们期望收到[44,11]和[8,23].在互联网上看,我发现了一个伟大的和geniaus解决方案,但不能理解背后的逻辑:
func :: [Int] -> ([Int], [Int])
func [] = ([], [])
func [x] = ([x], [])
func (x:y:xs) = (x:odds, y:evens)
where
(odds, evens) = func xs
型
我知道haskell中有“奇”和“偶”函数,但“奇s”和“偶s"是什么意思?这些值是如何正确地进入某个列表的?我为此感到疑惑。
我正在寻找几个论坛和教程,试图理解这段代码的逻辑,但我在零水平,直到现在。
2条答案
按热度按时间9rygscc11#
我知道haskell中有“奇”和“偶”函数,但是“奇s”和“偶s"是什么意思呢?
odds
和evens
只是变量名。它们与odd
和even
函数没有直接关系。它们是复数(以s
结尾),因为这是Haskell对列表的命名约定。让我们从
func [44, 8, 11, 23]
开始,逐步完成示例输入。由于这是一个递归函数,所以会有多个调用
func
,它们都有自己的局部变量。为了避免混淆,我将为每个调用的局部变量添加数字,例如x1
和x2
,而不仅仅是x
。首先,
func [44, 8, 11, 23]
匹配func
的第三个子句func (x : y : xs)
。字符串
这可以简化一点。
型
现在我们需要知道
func [11, 23]
的值。这也匹配第三个子句。型
再一次,我们可以简化。
型
最后,
func []
匹配第一个子句func [] = ([], [])
。型
所以我们可以继续简化,直到我们得到一个解决方案。
fkvaft9z2#
一件一件来:
字符串
当输入的长度>=2时,从
x
和y
开始,然后继续列表xs.型
.结果是一对,其第一个分量是
x : odds
,第二个分量是y : evens
。变量odds
和evens
定义为.型
.这些(列表)值是由递归调用
func xs
产生的。让我们举个例子:
型
为了完成计算,我们计算递归调用:
型
再递归调用一次computing,但这是立即的:
func [] = ([], [])
。所以我们有
型
发现了这一点后,我们从前面的方程中得到:
型
所以我们有
型
所以我们从更古老的方程中得到:
型