为什么product []返回1?

时间:2015-11-16 09:55:06

标签: haskell

为什么Haskell中的函数product如果给出一个空列表,则返回1

5 个答案:

答案 0 :(得分:19)

列表形成 monoid 结构,具有关联二进制操作++和中性元素[]。也就是说,我们有

[] ++ xs = xs = xs ++ []    (xs ++ ys) ++ zs = xs ++ (ys ++ zs)

与此同时,数字有很多幺半群结构,但这里的相关结构是操作为*而中性元素为1

1 * x = x = x * 1           (x * y) * z = x * (y * z)

product函数不仅是从数字到数字列表的映射:它是 monoid同态,反映了数字幺半群中的列表幺半群结构。至关重要的是,

product (xs ++ ys) = product xs * product ys

product [] = 1

事实上,为了获得前者,我们几乎将后者强加给我们。

答案 1 :(得分:8)

因为它是乘法类别中的身份。

更实际:

product [1,2,3] == 1 * product 2:3:[]
                == 1 * 2 * product 3:[]
                == 1 * 2 * 3 * product []

反过来允许您通过简单的递归来实现它:

product [] = 1
product (x:xs) = x * product xs

答案 2 :(得分:7)

这是一个数学问题 - 你通常会将一个空的和定义为0,将空的产品定义为1,因为这很符合你通常的法则

例如,通过这种方式,您可以证明产品的归纳定义 - see Wikipedia

答案 3 :(得分:2)

产品是初始值为1的折叠,因此当折叠空列表时,它只返回初始值,即1。

用于说明它的产品实施示例:

product :: [Int] -> Int
product lst = foldr (\x y -> x*y) 1 lst

请查看fold以正确理解。

答案 4 :(得分:0)

我认为这在@Bartek Banachewicz's answer中有最好的解释,但我只想补充一点,那就是所有这些都归结为数学中的一个著名问题;

为什么0!等于1

Empty元素不应破坏递归,换句话说,它的行为应类似于identity元素。总之,在数学上,阶乘的递归定义为;

n! = (n+1)! / (n+1)

因此,是Haskell美女

factorial :: Int -> Integer
factorial n = product [1..n]

可以正常工作。我的意思是没有测试n是否为0,即[1..0]产生[]。这可能是另一个问题主题。