6

假设我有两个函数f :: [a] -> bg :: [a] -> c. 我有以下两个问题:

  1. 如果我执行(f &&& g) xswhere xs :: [a],并且如果两者都f涉及g循环,编译器是否可以将这两个循环优化为一个循环?(请注意,我不是在问某些特定的 Haskell 编译器是否实现了这一点。我想知道这样的事情是否可能。)

  2. traverse类型类中的函数能否Traverse帮助我进行如下优化:

    traverse (someCombinator f g) xs
    
4

1 回答 1

9

理论上可以优化此代码,但非常非常困难,因为f并且g可能会消耗不同数量的输入列表。只有当它们消耗相同的数量,或者g总是消耗更多的列表f(或反之亦然)时,才有可能执行优化。停止问题阻止编译器检测复杂代码中的此类情况。

只有在简单的情况下,例如,两者都在f内部g使用foldr,才有可能在没有进一步自省的情况下执行微不足道的优化。

traverse函数在这里对您没有帮助,因为没有合理的实现方式someCombinator(您如何将多个a's 调用转换为一个[a]没有严重黑客攻击的调用?然后您又回到了您开始的地方)。

您唯一真正的选择是制作fg进入文件夹,以便它们具有签名f :: a -> b -> bg :: a -> c -> c,这意味着可以增量计算b和的值。c然后\ a -> f a *** g a,您可以使用来获取可以在常规(在本例中为正确)折叠中使用的文件夹。

于 2012-02-08T10:50:45.563 回答