我们可以xs在表达式的列表中融合两个遍历
(map f xs, map g xs)
Run Code Online (Sandbox Code Playgroud)
像这样
unzip (map (\x -> (f x, g x)) xs)
Run Code Online (Sandbox Code Playgroud)
有没有自动进行这种融合的研究?
(如果其中一个返回的列表在另一个之前被消耗,则存在创建空间泄漏的风险.我更有兴趣防止额外的遍历而xs不是节省空间.)
编辑:我实际上并不打算将融合应用于实际的内存中Haskell列表,其中这种转换可能没有意义,具体取决于是否unzip可以与其消费者融合.我有一个我知道unzip可以融合的设置(参见"FlumeJava:简单,高效的数据并行管道").
也不是全自动的,但你可以给 GHC 一个类似的重写规则列表。请参阅7.14 重写规则和使用规则。然后编译器在编译时使用这些规则来优化你的程序。(请注意,编译器不会以任何方式检查规则是否有意义。)
编辑:为了给出这个特定问题的例子,我们可以写:
{-# 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)
Run Code Online (Sandbox Code Playgroud)
(规则中的顶级函数名称是(,) :: a -> b -> (a, b))。编译时,您将看到如何应用规则。dump-rule-firings应用规则时选项会显示一条消息,并-ddump-rule-rewrites详细显示每个规则应用程序 - 请参阅7.14.6。控制重写规则中发生的事情。
| 归档时间: |
|
| 查看次数: |
313 次 |
| 最近记录: |