List 列表的乘积迭代

List 列表的乘积迭代,list,haskell,product,List,Haskell,Product,我正在尝试用Haskell学习编码 我从一个简单的例子开始,即列表的乘积 product :: [Integer] -> Integer product [] = 1 product (x:xs) = x * product xs 我很快就完成了。 另一种方法是API中的产品函数。产品列表->产品 我想知道是否有另一种迭代方法来解决我的问题?在Haskell中,我们没有循环,所以迭代是相对的,但这里是函数迭代方法 product = foldl' (*) 1 折叠是命

我正在尝试用Haskell学习编码

我从一个简单的例子开始,即列表的乘积

product :: [Integer] -> Integer  
product []     = 1  
product (x:xs) = x * product xs
我很快就完成了。 另一种方法是API中的产品函数。产品列表->产品


我想知道是否有另一种迭代方法来解决我的问题?

在Haskell中,我们没有循环,所以迭代是相对的,但这里是函数迭代方法

 product = foldl' (*) 1
折叠是命令式语言中循环的等价物。foldl'尤其是尾部递归且严格,因此它将在常量空间中运行,类似于循环

如果我们要明确地写出来

 product = go 1
   where go accum (x:xs) = go (accum * x) xs
         go accum _      = accum -- Subtle performances
                                 -- differences with strictness

这仍然是递归的,但将编译成类似的程序集。

在Haskell中,我们没有循环,因此迭代是相对的,但这里是函数迭代方法

 product = foldl' (*) 1
折叠是命令式语言中循环的等价物。foldl'尤其是尾部递归且严格,因此它将在常量空间中运行,类似于循环

如果我们要明确地写出来

 product = go 1
   where go accum (x:xs) = go (accum * x) xs
         go accum _      = accum -- Subtle performances
                                 -- differences with strictness
这仍然是递归的,但将编译为类似的程序集。

您可以使用折叠:

product :: Num a => [a] -> a
product xs = foldl (*) 1 xs
这也可以通过foldl'或foldr严格完成,主要区别在于性能,但由于您刚刚开始,我这次将跳过这节课

那么褶皱起什么作用呢?让我们从foldl的基本定义开始:

它所做的是接受一个函数f::a->b->a,它接受一个累加器和一个附加值,该值从值列表中馈送给它。它迭代地应用这个函数,在每一步生成一个新的累加器,直到列表中的值用完为止。因为它看起来像

> foldl (*) 1 [1, 2, 3, 4]
|   foldl (*) (1 * 1) [2, 3, 4] = foldl (*) 1 [2, 3, 4]
|   foldl (*) (1 * 2) [3, 4]    = foldl (*) 2 [3, 4]
|   foldl (*) (2 * 3) [4]       = foldl (*) 6 [4]
|   foldl (*) (6 * 4) []        = foldl (*) 24 []
|   24
我应该补充一点,除非您使用foldl',这是一个严格的版本,否则这并不是在内存中执行的方式,但这样做更容易。

您可以使用fold:

product :: Num a => [a] -> a
product xs = foldl (*) 1 xs
这也可以通过foldl'或foldr严格完成,主要区别在于性能,但由于您刚刚开始,我这次将跳过这节课

那么褶皱起什么作用呢?让我们从foldl的基本定义开始:

它所做的是接受一个函数f::a->b->a,它接受一个累加器和一个附加值,该值从值列表中馈送给它。它迭代地应用这个函数,在每一步生成一个新的累加器,直到列表中的值用完为止。因为它看起来像

> foldl (*) 1 [1, 2, 3, 4]
|   foldl (*) (1 * 1) [2, 3, 4] = foldl (*) 1 [2, 3, 4]
|   foldl (*) (1 * 2) [3, 4]    = foldl (*) 2 [3, 4]
|   foldl (*) (2 * 3) [4]       = foldl (*) 6 [4]
|   foldl (*) (6 * 4) []        = foldl (*) 24 []
|   24

我应该补充一点,除非使用foldl',这是一个严格的版本,否则它在内存中的执行方式并不完全相同,但按照这种方式更容易。

视情况而定。你说的迭代到底是什么意思?我指的是一种非递归的方法。不知道这是否可能。你自己不使用递归还是根本不使用递归?我认为后者在Haskell中是不可能的,但有许多函数可以为您执行特定的递归模式。根据您打算如何使用product,我可能会将null list设置为返回零。@groovy在数学和它的所有应用程序中,这不是积的常用定义,主要是因为在几乎所有情况下,空集的乘积为1更有用。如果有这种行为的用例,为了避免混淆,我不会称之为产品。另外,我很好奇:您是否考虑过用例?这取决于。你说的迭代到底是什么意思?我指的是一种非递归的方法。不知道这是否可能。你自己不使用递归还是根本不使用递归?我认为后者在Haskell中是不可能的,但有许多函数可以为您执行特定的递归模式。根据您打算如何使用product,我可能会将null list设置为返回零。@groovy在数学和它的所有应用程序中,这不是积的常用定义,主要是因为在几乎所有情况下,空集的乘积为1更有用。如果有这种行为的用例,为了避免混淆,我不会称之为产品。另外,我很好奇:你脑子里有一个用例吗?为什么要包含空列表用例,foldl自己不处理它吗?@delnan Habity,foldl会处理它,现在修复它为什么要包含空列表用例,foldl自己不处理它吗?@delnan Habity,foldl会处理它,现在修复它