假设我有两个函数f :: [a] -> b
和g :: [a] -> c
。我有以下两个问题:
如果我执行(f &&& g) xs
xs :: [a]
,f
和g
都涉及循环,编译器是否可以将这两个循环优化为一? (请注意,我不是在问一些特定的Haskell编译器是否实现了这一点。我想知道这样的事情是否可能。)
来自traverse
类型类的Traverse
函数是否可以帮助我对以下内容进行优化:
traverse (someCombinator f g) xs
答案 0 :(得分:9)
理论上可以优化此代码,但非常困难,因为f
和g
可能会消耗不同数量的输入列表。只有当它们消耗相同的金额时,或g
总是消耗更多的列表而不是f
(反之亦然),才有可能执行优化。暂停问题阻止编译器在复杂代码中检测到这种情况。
只有在f
和g
内部使用foldr
的简单情况下,才有可能在没有进一步内省的情况下执行琐碎的优化。
traverse
函数在这里没有帮助,因为没有合理的方法来实现someCombinator
(您希望如何将a
的多个调用转换为[a]
f
1}}没有严重的黑客攻击?然后你回到了你开始的地方。)
您唯一真正的选择是将g
和f :: a -> b -> b
放入文件夹,以便他们拥有签名g :: a -> c -> c
和b
,这意味着{{1}的值}}和c
可以递增计算。然后,您可以使用\ a -> f a *** g a
来获取可以在传统文件夹中使用的文件夹(在本例中为右侧)。