What code would you like to get? I think you are talking about specialising a recursive function ($fFunctorTree_$cfmap in this case) for a particular value of its function argument. That's a bit like SpecConstr (SpecFun perhaps) and nothing at all like inlining.
Unless I'm missing something. I think there's a ticket somewhere about extending SpecConstr to work on function arugments, but it's tricky to do. Simon | -----Original Message----- | From: David Feuer [mailto:da...@well-typed.com] | Sent: 30 January 2017 21:42 | To: ghc-devs@haskell.org; Simon Peyton Jones <simo...@microsoft.com> | Cc: David Feuer <david.fe...@gmail.com> | Subject: Re: Constant functions and selectors make for interesting | arguments | | Here's an example: | | data Tree a = Bin (Tree a) a (Tree a) | Tip deriving Functor | | {-# NOINLINE replace #-} | replace :: a -> Tree b -> Tree a | replace x t = x <$ t | | When I compile this with -O2, I get | | Rec { | -- RHS size: {terms: 18, types: 21, coercions: 0} $fFunctorTree_$cfmap | :: forall a_ar2 b_ar3. (a_ar2 -> b_ar3) -> Tree a_ar2 -> Tree b_ar3 | $fFunctorTree_$cfmap = | \ (@ a_aGb) | (@ b_aGc) | (f_aFH :: a_aGb -> b_aGc) | (ds_dGN :: Tree a_aGb) -> | case ds_dGN of _ { | Bin a1_aFI a2_aFJ a3_aFK -> | Bin | ($fFunctorTree_$cfmap f_aFH a1_aFI) | (f_aFH a2_aFJ) | ($fFunctorTree_$cfmap f_aFH a3_aFK); | Tip -> Tip | } | end Rec } | | $fFunctorTree_$c<$ | :: forall a_ar4 b_ar5. a_ar4 -> Tree b_ar5 -> Tree a_ar4 | $fFunctorTree_$c<$ = | \ (@ a_aGQ) (@ b_aGR) (eta_aGS :: a_aGQ) (eta1_B1 :: Tree b_aGR) -> | $fFunctorTree_$cfmap (\ _ -> eta_aGS) eta1_B1 | | replace :: forall a_aqt b_aqu. a_aqt -> Tree b_aqu -> Tree a_aqt replace | = $fFunctorTree_$c<$ | | This is no good at all, because replacing the values in the same tree | over and over will build up a giant chain of thunks in each node carrying | all the previous values. I suppose that inlining per se may not be quite | enough to fix this problem, but I suspect there's some way to fix it. | Fixing it in Functor deriving would be a start (I can look into that), | but fixing it in user code would be quite good too. | | On Monday, January 30, 2017 9:01:34 PM EST Simon Peyton Jones via ghc- | devs | wrote: | > Functions whose body is no bigger (by the inliner’s metrics) than the | call | > are always inlined vigorously. So (\.....-> k) replaces a call by a | > single variable. GHC will do that a lot. | | > These ideas are best backed by use-cases where something good is not | > happening. Do you have some? | | > Simon | > | > From: ghc-devs [mailto:ghc-devs-boun...@haskell.org] On Behalf Of | > David Feuer | Sent: 27 January 2017 16:42 | > To: ghc-devs <ghc-devs@haskell.org> | > Subject: Constant functions and selectors make for interesting | > arguments | > | > GHC's inliner has a notion of "interesting argument" it uses to | > encourage inlining of functions called with (I think) dictionary | > arguments. I think another class of argument is very interesting, by | > being very boring. Any argument that looks like either | | > \ _ ... (Con _ ... x ... _ ) ... _ -> coerce x | > | > or | > | > \ _ ... _ -> k | > | > Has a pretty good chance of doing a lot of good when inlined, perhaps | > plugging a space leak. Would it make sense to try to identify such | > functions and consider them interesting for inlining? | _______________________________________________ ghc-devs mailing list ghc-devs@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs