为什么GHC在内联时考虑LHS *的语法* [英] Why does GHC consider the LHS *syntactically* when inlining?

查看:62
本文介绍了为什么GHC在内联时考虑LHS *的语法*的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据GHC 文档


... GHC只会在函数完全应用时内联函数,其中
完全应用表示应用于与出现的参数一样多的参数$

其中给出的例子是两个语义等价的定义: b $ b(语法上)在函数定义的LHS上。 p>

  comp1 ::(b  - > c) - > (a  - > b) - > a  - > c 
{ - #INLINE comp1# - }
comp1 f g = \ x - > f(g x)

comp2 ::(b→c)→> (a - > b) - > a - > c
{ - #INLINE comp2# - }
comp2 fgx = f(gx)

我的问题:


  1. 是否只有在INLINE pragmas的存在下才能得到这个严格的
    行为(即LHS的严格语法视图,RHS内联,不包括
    优化)?

  2. 当没有给出INLINE pragmas时,GHC是否会转换函数
    comp2 comp1


  3. 如果不是,为什么?一般来说,编译器在函数的语义中查找
    并确定
    部分应用和INLINE有多少以及在哪里是非常困难的?


  4. 如果GHC只是将所有函数转换为
    级联的 let ...在表达式中使用lambda表达式且在$ b上没有绑定,会发生什么情况$ b the LHS?



解决方案

code> c 本身就是一个函数类型?我不清楚你的提案在这种情况下会如何解决。



在任何情况下,肯定有一些情况你不希望所有函数的参数拉到前面。例如,你可能有这样的代码:

  foo :: [Int]  - > Int  - > Int  - > Int 
foo list = let
- 昂贵的预计算在这里
bar x y = ...
in \ x y - > bar xy

您需要 foo 获得部分应用,然后对结果函数的多个应用程序共享昂贵的预计算工作。相反,如果您将其作为 foo list x y 前移,您将无法分享昂贵的预计算。 (我在严重的应用程序中遇到过这种情况。)


According to the GHC docs:

...GHC will only inline the function if it is fully applied, where "fully applied" means applied to as many arguments as appear (syntactically) on the LHS of the function definition.

Where the example given is two semantically-equivalent definitions:

comp1 :: (b -> c) -> (a -> b) -> a -> c
{-# INLINE comp1 #-}
comp1 f g = \x -> f (g x)

comp2 :: (b -> c) -> (a -> b) -> a -> c
{-# INLINE comp2 #-}
comp2 f g x = f (g x)

My questions:

  1. Is it only in the presence of INLINE pragmas that we get this strict behavior (i.e. strict syntactic view of LHS, RHS inlined w/out optimizations)?

  2. when no INLINE pragmas are given, does GHC ever transform a function like comp2 to comp1?

  3. if not, why? Is it too difficult in general for the compiler to look at the semantics of the function and decide how much and where to partially-apply and INLINE?

  4. what would happen if GHC just transformed all functions into a cascade of let... in expressions with lambdas and no bindings on the LHS?

解决方案

What if, in this example, c is itself a function type? I'm not clear how your proposal would work out in that scenario.

In any event, there are definitely cases where you don't want all of a function's arguments "pulled to the front." For example, you might have some code like this:

foo :: [Int] -> Int -> Int -> Int
foo list = let
  -- expensive precomputation here
  bar x y = ...
  in \ x y -> bar x y

You want foo to get partially applied, and then for multiple applications of the resulting function to share the expensive precomputation work. If instead you pulled it forward as foo list x y, you wouldn't get to share that expensive precomputation. (I've encountered this case in serious applications.)

这篇关于为什么GHC在内联时考虑LHS *的语法*的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆