Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
List 列表中相邻元素乘积的Haskell函数_List_Function_Haskell_Recursion - Fatal编程技术网

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

List 列表中相邻元素乘积的Haskell函数,list,function,haskell,recursion,List,Function,Haskell,Recursion,我试图创建一个Haskell函数,其中输入是一个整数列表,输出是所述列表中相邻元素的乘积的新列表。这是我目前的代码: productsList :: [Integer] -> [Integer] productsList [] = [] productsList (x:[]) = [] productsList (x:y:xs) = [x * y] ++ productsList xs 但是,当我在GHC中检查时,虽然它编译得很好,但输出是错误的。例如,当我尝试: productsLis

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

productsList :: [Integer] -> [Integer]
productsList [] = []
productsList (x:[]) = []
productsList (x:y:xs) = [x * y] ++ productsList xs
但是,当我在GHC中检查时,虽然它编译得很好,但输出是错误的。例如,当我尝试: productsList[1..3],输出为:[2],这显然只是列表中前两个元素的乘积。这里的正确答案应该是[2,6]。对我来说,可能的问题可能在于,我的案例不包括有x但没有y的情况,尽管我认为productsList x:[]=[]行中包含了它


有人能帮我找出导致输出变化的原因吗?

有一个相当常见的习惯用法:zip tail==\xs->zip xs tail xs为您提供了相邻对的列表。由于zip在第二个参数中是非严格的,所以它也适用于空列表

> zip <*> tail $ [1,2,3]
[(1,2),(2,3)]
> zip <*> tail $ []
[]
因此,可以使用简单的列表理解来定义函数:

productsList :: [Integer] -> [Integer]
productsList xs = [x*y | (x, y) <- zip <*> tail $ xs]
让我们逐步评估产品列表[1..3]:

产品列表[1..3] =产品列表1:2:[3] =[1*2]++productsList[3] = [1*2] ++ [] = [1*2] 因此这里的问题是productsList x:y:xs=[x*y]++productsList xs根据需要乘以x和y,但随后在xs而不是y:xs上递归。这意味着productsList[a,b,c,d,e,f,…]将计算[a*b,c*d,e*f,…],而不是所需的[a*b,b*c,c*d,d*e,e*f,f*…]。要解决这个问题,您需要在y:xs上递归,正如我在上面简要提到的,而不仅仅是xs:

productsList::[Integer]->[Integer] 产品列表[]=[] 产品列表x:[]=[] productsList x:y:xs=[x*y]++productsList y:xs 现在,该函数的计算如下:

产品列表[1..3] =产品列表1:2:[3] =[1*2]++产品列表2:[3] =[1*2]++产品列表2:3:[] =[1*2]++[2*3]++产品列表3:[] = [1*2, 2*3] ++ [] = [1*2, 2*3]
什么是测试xs?我假设这是productsList xs的输入错误。顺便说一句,[x*y]++test xs相当于x*y:test xs,它更简单,也可能更快一点。@bradrn你是对的。谢谢,我编辑了OP。因为我对Haskell和函数式编程都是新手,所以我不知道zip!我猜这又回到了文档中。这个答案很好,谢谢。如果我们想用一种奇特的方式来做,为什么不简单地用productsList=zipWith*tail呢?我玩过zipWith和配对列表,但我对配对太着迷了,我从来没有想到过这种方法。而且,总体来说,似乎是不加修饰地映射f。zip g==zipWith f g。感谢您通过评估对其进行解释。作为函数式编程的新手,如您所示,直观地查看它对我非常有帮助。我将检查这个答案,因为它更符合我从代码中得到的总体想法。感谢您的深入和周到的回答!不客气@drPepper!