假设我有两个函数f :: [a] -> b
和g :: [a] -> c
. 我有以下两个问题:
如果我执行
(f &&& g) xs
wherexs :: [a]
,并且如果两者都f
涉及g
循环,编译器是否可以将这两个循环优化为一个循环?(请注意,我不是在问某些特定的 Haskell 编译器是否实现了这一点。我想知道这样的事情是否可能。)traverse
类型类中的函数能否Traverse
帮助我进行如下优化:traverse (someCombinator f g) xs
假设我有两个函数f :: [a] -> b
和g :: [a] -> c
. 我有以下两个问题:
如果我执行(f &&& g) xs
where xs :: [a]
,并且如果两者都f
涉及g
循环,编译器是否可以将这两个循环优化为一个循环?(请注意,我不是在问某些特定的 Haskell 编译器是否实现了这一点。我想知道这样的事情是否可能。)
traverse
类型类中的函数能否Traverse
帮助我进行如下优化:
traverse (someCombinator f g) xs
理论上可以优化此代码,但非常非常困难,因为f
并且g
可能会消耗不同数量的输入列表。只有当它们消耗相同的数量,或者g
总是消耗更多的列表f
(或反之亦然)时,才有可能执行优化。停止问题阻止编译器检测复杂代码中的此类情况。
只有在简单的情况下,例如,两者都在f
内部g
使用foldr
,才有可能在没有进一步自省的情况下执行微不足道的优化。
该traverse
函数在这里对您没有帮助,因为没有合理的实现方式someCombinator
(您如何将多个a
's 调用转换为一个[a]
没有严重黑客攻击的调用?然后您又回到了您开始的地方)。
您唯一真正的选择是制作f
和g
进入文件夹,以便它们具有签名f :: a -> b -> b
和g :: a -> c -> c
,这意味着可以增量计算b
和的值。c
然后\ a -> f a *** g a
,您可以使用来获取可以在常规(在本例中为正确)折叠中使用的文件夹。