Function foldr的相同融合法则能否应用于foldlmap?
我已经读过,光是Function foldr的相同融合法则能否应用于foldlmap?,function,haskell,functional-programming,mapreduce,fold,Function,Haskell,Functional Programming,Mapreduce,Fold,我已经读过,光是foldl没有融合法则。如果我猜对了,这是由于foldl在实现map时的笨拙-这主要是由于(foldl cons nil xs)颠倒了列表 如果改为使用conc列表,则函数foldlmap在这方面会更好: (foldlmap list conc nil xs) -> xs 如果我的猜测是正确的,那么foldlmap应该有一个简单的融合法则。这是否正确?我们可以从显式连接列表类型的“自然”折叠构建融合规则开始: {-# LANGUAGE RankNTypes #-} da
foldl
没有融合法则。如果我猜对了,这是由于foldl
在实现map时的笨拙-这主要是由于(foldl cons nil xs)
颠倒了列表
如果改为使用conc
列表,则函数foldlmap
在这方面会更好:
(foldlmap list conc nil xs) -> xs
如果我的猜测是正确的,那么foldlmap
应该有一个简单的融合法则。这是否正确?我们可以从显式连接列表类型的“自然”折叠构建融合规则开始:
{-# LANGUAGE RankNTypes #-}
data ConcList a = List a | Conc (ConcList a) (ConcList a) | Nil
buildCL :: (forall l . (a -> l) -> (l -> l -> l) -> l -> l) -> ConcList a
buildCL g = g List Conc Nil
foldCL :: (a -> v) -> (v -> v -> v) -> v -> ConcList a -> v
foldCL list conc nil cl = go cl
where
go (List a) = list a
go (Conc cl1 cl2) = conc (go cl1) (go cl2)
go Nil = nil
{-# RULES "foldCL/buildCL"
forall list conc nil
(g :: (forall l . (a -> l) -> (l -> l -> l) -> l -> l))
. foldCL list conc nil (buildCL g) = g list conc nil #-}
从理论上讲,这相当于“正常”列表:
但是列表上的
foldr/build
的美妙之处在于它适用于很多事情,因为很多函数是“自然生产者”(可以用build
重写),而很多函数是自然消费者(可以用foldr
重写)。我认为模式foldl/map/buildCL2
更难设计。你在考虑什么样的融合法则-等效的foldr
法则是什么?你能给出Haskell对conc
列表和foldlmap
的定义,这样细节就清楚了吗?[我们想到的foldr
的自然融合法则是h(foldr f e xs)=foldr f'e'xs
在各种函数的适当条件下,但这对于编译器来说很难自动应用,因此您可能也会想到类似于foldr build
或类似的事情]我说的是允许编译器转换(map f(map g xs))->(map(f.g)xs)
的融合重写法则。(编辑:是的,你说的。)conc
只是通常的连接foldlmap f g z xs=foldl g z(map f xs)
。
buildCL2 :: (forall l . (a -> l) -> (l -> l -> l) -> l -> l) -> [a]
buildCL2 g = g (\a -> [a]) (++) []
{-# RULES "foldl/map/buildCL2"
forall list conc nil
(g :: (forall l . (a -> l) -> (l -> l -> l) -> l -> l))
. foldl conc nil (map list (buildCL2 g)) = g list conc nil #-}