部分评估右手操作员部分

Dou*_*ean 14 performance haskell ghc

我有一个功能(*~).评估的大部分成本x *~ y来自检查第二个论点,大致如下:

(*~) :: a -> b d -> c d a
x *~ y = case y' of
           Bar -> cheapFunction y' x
           Baz -> cheapFunction2 y' x
           Quux -> cheapFunction3 y' x
  where
    y' = expensive y
Run Code Online (Sandbox Code Playgroud)

有没有办法说服GHC部分评估运营商部分(*~ y)

我尝试重写它像:

(*~) = flip go
  where
    go y = let y' = expensive y
            in case y' of
                 Bar -> cheapFunction y'
                 Baz -> cheapFunction2 y'
                 Quux -> cheapFunction3 y'
Run Code Online (Sandbox Code Playgroud)

但它似乎没有帮助.我想这可能是因为flip在它翻转之前需要所有它的参数?

一种方法就是翻转操作符本​​身,但是当昂贵的操作数位于右侧时,它会更自然地读取,因为它与现有符号对齐.

一个精心制作的{-# RULE #-}保释可以在这里保释吗?如果是这样,它应该说什么?(我不清楚在规则查找匹配之前,分段语法会在多大程度上消失掉.)

Nik*_*kov 5

要触发此类优化,您需要确保您的函数内联.{-# INLINE (*~) #-}(*~)函数声明之前放置pragma .我不能保证你会解决你的问题,但这是我看到它被接近的唯一方式.之后我会用"ghc-core"之类的工具检查生成的核心代码,以确保.

但是,您的问题实际上只是代码组成不正确的指示.你的功能正在做多个无关的事情.expensive y应该简单地将其考虑在内,那么你的问题就会被删除.即,使用模式应该是x *~ expensive y代替x *~ y.

  • 实际上,它也不是你的情况下隐藏的实现细节,你只是以不同的方式暴露它.你也会混淆你的意图并将其隐藏在类型系统中,因此必须告知用户你的特殊功能应该如何使用.从可用性的角度来看,这可能不太好.而且,它再次反对分离关注点.你有一个关于你的方法已经不正确的指示清单,所以最好三思而后行. (2认同)