【问题标题】:why pipes defines inner functions为什么管道定义内部功能
【发布时间】:2015-09-19 01:09:57
【问题描述】:

我正在查看 pipes 库源代码,例如在 Core module 中,我不明白为什么作者到处使用这样的定义函数的模式:

runEffect = go
  where
    go p = ...

或者:

pull = go
  where
    go a' = ...

或者:

reflect = go
  where
    go p = ...

这是启用某些优化的技巧吗?我觉得它很难看,如果它是一些优化技巧,我真的希望编译器可以在没有这样的事情的情况下做到这一点。但也许还有其他原因?

【问题讨论】:

    标签: haskell ghc haskell-pipes


    【解决方案1】:

    GHC 只会内联非递归函数,并且仅当它们从句法的角度“完全应用”时(即在调用站点,它们被应用于出现在左侧的参数数量)定义)。

    在您发布的示例中没有参数,但是定义可能是递归的并且不会被内联。进行这种转换可能允许在调用站点内联和专门化定义(对于m 等的具体类型)。

    这是启用某些优化的技巧吗?我觉得很丑,如果 这是一些优化技巧,我真的希望编译器能做到 没有类似的东西。

    是的,它超级蹩脚。

    【讨论】:

    • pipes 是一个具有可组合抽象的小型库,可用于构建许多复杂的逻辑,因此在核心库级别进行大量优化是很自然的。它还具有重要的重写规则。相反,在正常的生产代码中,我们不需要关心手动工人包装器。 GHC 通常可以做到这一点。
    • 谢谢。感谢您的关键字“完全应用”,我现在偶然发现了这个:stackoverflow.com/questions/11690146/…,我希望能为我分享更多关于这个问题的信息。当您看到 haskell 可以实现的所有其他魔法时,这非常令人失望。
    • 如果“内联”递归函数这么容易,为什么 GHC 不自己做这个技巧?
    • 顺便说一句,如果重要的是出现在 LHS 上的参数数量,你能写runEffect = \p -> ... 并获得相同的性能特征吗?我认为那看起来不那么难看。
    • @EmmanuelTouzery " 你能写runEffect = \p -> ..." 是的,这通常用于非递归函数。
    猜你喜欢
    • 2021-06-14
    • 1970-01-01
    • 2021-06-12
    • 1970-01-01
    • 2017-11-17
    • 1970-01-01
    • 2017-09-21
    • 2016-07-06
    • 1970-01-01
    相关资源
    最近更新 更多