Haskell 很难理解笛卡尔乘积中的变换foldr
我跟着去理解高阶函数的组合 我得到了一个重要的转变,我认为要直接理解它并不容易:Haskell 很难理解笛卡尔乘积中的变换foldr,haskell,lambda,functional-programming,fold,cartesian-product,Haskell,Lambda,Functional Programming,Fold,Cartesian Product,我跟着去理解高阶函数的组合 我得到了一个重要的转变,我认为要直接理解它并不容易: 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 甚至我也得到了这些帮助
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)
所以我的问题是:解释转换容易吗?本质上,它归结为
h
是xs
上的递归函数,而foldr
概括了列表上的递归。注意h
如何在尾部调用自身xs
,就像foldr
在尾部调用自身as
通过对
ws
的归纳,证明hws-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
,假设hxs-xss=h''xs-xss
(归纳假设)
首先创建一个内部函数,不使用第二个参数
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
然后,让我们看看如何使用另一个作用于x
和递归调用结果h'xs
的辅助函数来抽象出h'
中的递归模式:
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
如果我们不想在h'
中显式写出列表递归,那么这就是我们将传递给foldr
的帮助函数:
h xs xss = foldr g [] xs
where
g x zss = foldr f zss xss
where
f xs ys = (x:xs) : ys
提供
h
和h'
的类型也会很有帮助。helper funcg
类似于foldr
定义中的f
,其中f
是需要传递的参数。这里g
就像在运行时一样放在那里。很好,很清楚。如果有人想看一下:
h xs xss = foldr g [] xs
where
g x zss = foldr f zss xss
where
f xs ys = (x:xs) : ys