笛卡尔积中的变换折叠器很难理解

时间:2018-05-21 11:11:15

标签: haskell lambda functional-programming product fold

我按照On Barron and Strachey's cartesian product function来理解高阶函数的组合。

我得到了一个重要的转变,我认为直截了当地理解它并不容易:

h [] xss = []
h (x : xs) xss =
 foldr f (h xs xss) xss where 
    f xs ys = (x: xs) : ys

等于这个:

h'' xs xss = 
foldr g [] xs where
    g x zss = foldr f zss xss where 
        f xs ys = (x : xs) : ys

即使我得到了这些帮手:

foldr :: (a -> b -> b) -> b -> [a] -> b
foldr f z [] = z
foldr f z (a:as) = f a (foldr f z as) 

-- change the name
h' :: (a -> b -> b) -> b -> [a] -> b
h' f z [] = z
h' f z (a:as) = f a (h' f z as)  

所以我的问题是:解释变换是否容易?

2 个答案:

答案 0 :(得分:4)

首先创建一个内部函数,而不使用仅执行标准列表递归的第二个参数xss

h []     xss = []
h (x:xs) xss = foldr f (h xs xss) xss
  where 
    f xs ys = (x:xs) : ys

  -->

h xs xss = h' xs
  where
    h' []     = []
    h' (x:xs) = foldr f (h' xs) xss
      where
        f xs ys = (x:xs) : ys

然后让我们看看我们如何使用另一个作用于h'的辅助函数和递归调用结果x来抽象h' xs中的递归模式:

h xs xss = h' xs
  where
    h' []     = []
    h' (x:xs) = g x (h' xs)
    g x zss = foldr f zss xss
      where 
        f xs ys = (x:xs) : ys

如果我们不想在foldr中明确写出列表递归,那么我们将传递给h'的辅助函数:

h xs xss = foldr g [] xs
  where
    g x zss = foldr f zss xss
      where 
        f xs ys = (x:xs) : ys

答案 1 :(得分:3)

从本质上讲,它归结为hxs上的递归函数,而foldr推广了列表上的递归。请注意h如何在尾部xs上调用自身,就像foldr在尾as上调用自身一样。

通过ws上的归纳,证明h ws xss = h'' ws xss。通过归纳推理,有两种情况需要考虑。

基本情况ws = []

h [] xss = []  -- by definition of h

h'' [] xss
= foldr g [] xss  -- by definition of h''
= []              -- by definition of foldr

归纳步骤ws = x : xs,假设h xs xss = h'' xs xss(归纳假设)

h (x : xs) xss
= foldr f (h xs xss) xss    -- by definition of h (N.B. f depends on x)
= foldr f (h'' xs xss) xss  -- by induction hypothesis
= g x (h'' xs xss)          -- by definition of g (N.B. g depends on xss)
= g x (foldr g [] xs)       -- by definition of h''
= foldr g [] (x : xs)       -- by definition of foldr
= h'' (x : xs) xss          -- by definition of h''