我们可以在表达式中的列表xs上融合两次遍历
(map f xs, map g xs)就像这样
unzip (map (\x -> (f x, g x)) xs)有没有关于自动执行这种融合的研究?
(如果其中一个返回的列表在另一个列表之前被使用,则会有造成空间泄漏的风险。我更感兴趣的是防止xs上的额外遍历,而不是节省空间。)
编辑:我实际上并不打算将这种融合应用于实际的内存中的Haskell列表,在这种情况下,这种转换可能没有意义,这取决于unzip是否可以与它的使用者进行融合。我有一个我知道unzip可以融合的设置(参见"FlumeJava:简单、高效的数据并行管道“)。
发布于 2012-09-03 15:35:01
也不是完全自动的,但是你可以给GHC一个类似的重写规则列表。参见7.14 Rewrite rules和Using rules。然后编译器在编译时使用这些规则来优化您的程序。(请注意,编译器不会检查规则是否有任何意义。)
编辑:为了给出这个特殊问题的例子,我们可以这样写:
{-# OPTIONS_GHC -fenable-rewrite-rules -ddump-rule-firings -ddump-rule-rewrites #-}
import Data.Char
{-# RULES
"map/zip" forall f g xs. (,) (map f xs) (map g xs) = unzip (map (\x -> (f x, g x)) xs)
#-}
main :: IO ()
main = let x = "abCD" in
print $ (,) (map toUpper x) (map toLower x)(规则中的顶级函数名称为(,) :: a -> b -> (a, b))。在编译时,您将看到规则是如何应用的。应用规则时,选项dump-rule-firings会显示一条消息,而-ddump-rule-rewrites会详细显示每个规则应用程序-请参阅7.14.6. Controlling what's going on in rewrite rules。
发布于 2012-09-04 01:10:35
我设法找到了两个资源,其中提到了融合(非)zip类函数,至少是简短的:
约瑟夫·斯文宁森。“参数累加的快捷融合&类Zip函数”http://www.cse.chalmers.se/~josefs/publications/fusion.pdf
邓肯·库茨。“流融合:共归纳序列类型的实用快捷融合”https://community.haskell.org/~duncan/thesis.pdf
然而,这两个资源都没有明确提到这种“兄弟融合”。
https://stackoverflow.com/questions/12241992
复制相似问题