【问题标题】:What does f [] = v mean in the Foldr Recursion Pattern?f [] = v 在 Foldr 递归模式中是什么意思?
【发布时间】:2018-09-19 18:09:35
【问题描述】:

当对函数积使用递归的Foldr模式时,我们得到:

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

我的问题是,“product [] = 1”是什么意思?例如,对于 sum 函数,我们有 sum[] = 0?这是对答案的某种限制吗?

提前谢谢你。

【问题讨论】:

  • 你了解“foldr递归模式”吗?
  • “无积”等于 1 是通常的数学约定。
  • 空值列表的乘积是什么?
  • 谢谢斯蒂芬,我完全错过了其中的逻辑!
  • 一般来说,foldLikeThing [] = memptyfoldLikeThing (x:xs) = x `mappend` foldLikeThing xs。 (参照foldrfoldMap的定义。)

标签: haskell recursion fold


【解决方案1】:

product [] 是基本情况。通过对函数的评估,很容易看出它存在的原因。

product [5, 4, 8]
5 * product [4, 8]
5 * 4 * product [8]
5 * 4 * 8 * product []
5 * 4 * 8 * 1
160

如果基本情况不存在,产品 [] 将无法评估任何内容。 1 是乘法的恒等式,就像 0 是加法的恒等式一样,即任何数的 1 倍始终是该数,就像 0 加任何数是该数一样。

【讨论】:

    【解决方案2】:

    要让x = product [x] 成立,product [] = 1 必须成立,因为根据你的定义,

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

    但从更广的角度来看(即考虑到xs == xs ++ []),

    product (xs ++ ys) = product xs * product ys    -- and so,
    
    product (xs ++ []) = product xs * product []
    

    because

    product = foldr (*) 1 = getProduct . foldMap Product
    

    根据 1986 年 Richard Bird 的 An Introduction to the Theory of Lists,使用关联运算(如乘法)进行归约(折叠)是列表上的 homomorphism(反之亦然),即

    foldr (*) 1 (xs ++ ys)  =  foldr (*) 1 xs  *  foldr (*) 1 ys   -- and so,
    
    foldr (*) 1 (xs ++ [])  =  foldr (*) 1 xs  *  foldr (*) 1 []
    

    从数学上讲,带有(*)1 的数字形成monoid。 Monoids 与 Haskell 中的折叠密切相关:

    foldMap :: Monoid m => (a -> m) -> f a -> m    
    

    在上面,f 是一个Foldable 类型,其中lists ([]) 就是其中之一。所以这一切都联系在一起了。

    【讨论】:

    • 你的意思是Foldable?列表是TraversableTraversableFoldable 的子类,但似乎并不完全相关。
    • @dfeuer 是的,谢谢。一个想法。这与 Bird 的“折叠成幺半群是同态”有关。那么它应该与“monads are high-order monoids”联系起来,我一直在脑海中搅动......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-11-24
    • 2020-03-03
    • 1970-01-01
    • 2016-07-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多