我按照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)
所以我的问题是:解释变换是否容易?
答案 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)
从本质上讲,它归结为h
是xs
上的递归函数,而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''