Hen*_*nry 1 haskell eclipse-fp
我只是在学习Haskell而且有点卡住了.我想比较列表元素并测量它们之间的差异并返回最高的元素.不幸的是,我不知道如何解决这个问题.通常,我只是迭代列表并比较邻居,但这似乎不是Haskell的方式.我已经尝试过使用,map但正如我所说,我真的不知道如何解决这个问题.我会感谢各种建议!
最好的祝愿
编辑:我的想法是首先拉链这样的所有对pairs a = zip a (tail a).然后我想得到所有的差异(可能与map?)然后只选择最高的一个.我只是无法处理Haskell语法.
我不知道你的意思是"测量列表元素之间的差异",但如果你想计算列表中的"最大"元素,你就会使用内置maximum函数:
maximum :: Ord a => [a] -> a
Run Code Online (Sandbox Code Playgroud)
此函数采用可以排序的值列表,因此包括所有数字,字符和字符串等.
如果要获得最大值和最小值之间的差异,可以使用类似的函数minimum,然后只需减去两者.当然,可能会有一个稍微快一点的解决方案,你只需要遍历列表一次,或者你可以对列表进行排序然后采用第一个和最后一个元素,但是对于大多数情况来说,这样做diff xs = maximum xs - minimum xs足够快,并且对其他人来说最有意义.
所以你想要做的是计算连续元素之间的差异,而不是计算每个元素的最小值和最大值.您不需要直接索引,而是使用一个方便的函数调用zipWith.它需要一个二进制操作和两个列表,并使用该二进制操作将它们"压缩"在一起.所以像
zipWith (+) [1, 2, 3] [4, 5, 6] = [1 + 4, 2 + 5, 3 + 6] = [5, 7, 9]
Run Code Online (Sandbox Code Playgroud)
它非常方便,因为如果其中一个列表提前耗尽,它就会停在那里.所以你可以做点什么
diff xs = zipWith (-) xs ???
Run Code Online (Sandbox Code Playgroud)
但是我们如何将列表偏移1?嗯,简单(和安全)的方式是使用drop 1.您可以使用tail,但如果xs是空列表,它会抛出错误并导致程序崩溃,但drop不会
diff xs = zipWith (-) xs $ drop 1 xs
Run Code Online (Sandbox Code Playgroud)
所以一个例子就是
diff [1, 2, 3, 4] = zipWith (-) [1, 2, 3, 4] $ drop 1 [1, 2, 3, 4]
= zipWith (-) [1, 2, 3, 4] [2, 3, 4]
= [1 - 2, 2 - 3, 3 - 4]
= [-1, -1, -1]
Run Code Online (Sandbox Code Playgroud)
此函数将返回正值和负值,我们只对幅度感兴趣,因此我们可以使用该abs函数:
maxDiff xs = ??? $ map abs $ diff xs
Run Code Online (Sandbox Code Playgroud)
然后使用我在上面突出显示的功能:
maxDiff xs = maximum $ map abs $ diff xs
Run Code Online (Sandbox Code Playgroud)
而且你已经完成了!如果你想要花哨,你甚至可以用无点符号来写这个
maxDiff = maximum . map abs . diff
Run Code Online (Sandbox Code Playgroud)
现在,这实际上会在空列表上maximum []引发错误,因为会抛出错误,但我会让你找到解决这个问题的方法.