列表中相邻元素乘积的 Haskell 函数

drP*_*per 0 recursion haskell function list

我正在尝试创建一个 Haskell 函数,其中输入是整数列表,输出是所述列表中相邻元素的乘积的新列表。这是我当前的代码:

productsList :: [Integer] -> [Integer]
productsList [] = []
productsList (x:[]) = []
productsList (x:y:xs) = [x * y] ++ productsList xs
Run Code Online (Sandbox Code Playgroud)

但是,当我在 GHC 中检查它时,虽然它编译正常,但输出是错误的。例如,当我尝试:时 productsList [1..3],输出是:[2],这显然只是列表中前两个元素的乘积(这里的正确答案应该是[2, 6])对我来说,似乎可能的问题在于我的情况当有 x 但没有 y 时不覆盖,虽然我认为它被覆盖在行中productsList (x:[]) = []

谁能帮我弄清楚是什么导致了这种输出变化?

che*_*ner 5

对此有一个相当常见的习语:zip <*> tail == \xs -> zip xs (tail xs)为您提供相邻对的列表。(并且因为zip它的第二个参数是非严格的,所以它也适用于空列表。)

> zip <*> tail $ [1,2,3]
[(1,2),(2,3)]
> zip <*> tail $ []
[]
Run Code Online (Sandbox Code Playgroud)

所以你的函数可以使用一个简单的列表理解来定义:

productsList :: [Integer] -> [Integer]
productsList xs = [x*y | (x, y) <- zip <*> tail $ xs]
Run Code Online (Sandbox Code Playgroud)

  • 如果我们要用奇特的方式来做,为什么不简单地使用“productsList = zipWith (*) &lt;*&gt; tail”呢? (4认同)