Haskell 所提出的情况是否可能优化为一个循环?

Haskell 所提出的情况是否可能优化为一个循环?,haskell,functional-programming,combinators,Haskell,Functional Programming,Combinators,假设我有两个函数f::[a]->b和g::[a]->c。我有以下两个问题: 如果我执行(f&&g)xs,其中xs:[a],并且如果f和g都涉及循环,编译器是否可以将这两个循环优化为一个循环?(请注意,我不是问某个特定的Haskell编译器是否实现了这一点。我想知道这样的事情是否可行。) traverse类型类中的traverse函数是否可以帮助我进行如下优化: traverse (someCombinator f g) xs 理论上可以优化此代码,但非常困难,因为f和g可能会消耗不同数量的输

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

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

  • traverse
    类型类中的
    traverse
    函数是否可以帮助我进行如下优化:

    traverse (someCombinator f g) xs
    

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

    例如,只有在简单的情况下,
    f
    g
    都在内部使用
    foldr
    ,才有可能在没有进一步内省的情况下执行琐碎的优化

    traverse
    函数在这里对您没有帮助,因为没有合理的方法实现
    someCombinator
    (您希望如何将
    a
    的多个调用转换为一个
    [a]
    ,而不进行严重的黑客攻击?然后您又回到了起点)


    您唯一的实际选择是将
    f
    g
    放入文件夹中,以便它们具有签名
    f::a->b->b
    g::a->c->c
    ,这意味着
    b
    c
    的值可以增量计算。然后,您可以使用
    \a->fa***ga
    获得一个文件夹,您可以在常规(本例中为右)折叠中使用该文件夹。

    回答得很好。谢谢!我发布这个问题是因为我想检查我在回答和评论中所说的是否正确。可以由超级编译器执行。