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 #-}