<div dir="auto"><div>sequence never helps anyone with anything, optimization-wise. I should double check that I wasn't working in a weird compilation environment or something when I checked the most recent version. GHC doesn't like to fire rules that might duplicate work, and Q may well be too general on the inside for the compiler to be able to tell. Do those Q things *ever* get specialized? If so, to what, and when?<br><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, Sep 22, 2022, 3:12 PM Joachim Breitner <<a href="mailto:mail@joachim-breitner.de">mail@joachim-breitner.de</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
 
  
 
 <div>
  <div style="font-family:sans-serif">
   <span dir="ltr" style="margin-top:0;margin-bottom:0">A simple composition of a pure [Type] -> Type function, fmap'ped and Control.Monad.sequence is not going to help, is it? At least the sequence might fuse with a producer, not sure if the fmap then gets in the way to fuse with the pure function though.</span> <br>
  </div>
  <div>
   <br>
   <div>
    <p>22.09.2022 20:14:20 David Feuer <<a href="mailto:david.feuer@gmail.com" target="_blank" rel="noreferrer">david.feuer@gmail.com</a>>:</p>
   </div>
   <blockquote style="margin:0;border-left:3px solid #ccc;padding-left:10px">
    <div dir="auto">
     <div>
      The recursion is the first barrier. The whole thing ends up a loop breaker. Using `fix` fixes that, but it still doesn't fuse for some reason. After I sent this, I realized that foldl' is really the wrong thing, since that builds up a large Q action that, when run, produces the expression. The nicer thing is to use foldM within Q, and wrap mfix around that. I'm still not seeing fusion with that, and I wonder if that's because of the complexity of the Q type with its higher-rank constrained polymorphism and such.
     </div>
     <div dir="auto">
      <br>
      <div class="gmail_quote" dir="auto">
       <div dir="ltr" class="gmail_attr">
        On Thu, Sep 22, 2022, 1:56 PM Joachim Breitner <<a href="mailto:mail@joachim-breitner.de" target="_blank" rel="noreferrer">mail@joachim-breitner.de</a>> wrote:<br>
       </div>
       <blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
        Hi,<br> <br> Am Sonntag, dem 11.09.2022 um 19:05 -0400 schrieb David Feuer:<br> > The template-haskell package has functions `tupE` and `tupP` for<br> > building tuple expressions and patterns, respectively, but nothing<br> > really similar for building tuple types. I came up with the version<br> > below the other day:<br> > <br> > -- | Given a list of types, produce the type of a tuple of<br> > -- those types. This is analogous to 'tupE' and 'tupP'.<br> > --<br> > -- @<br> > -- tupT [[t|Int|], [t|Char|], [t|Bool]] = [t| (Int, Char, Bool) |]<br> > -- @<br> > tupT :: [Q Type] -> Q Type<br> > tupT ts = n `seq` res<br> >   where<br> >     -- We build the expression with a thunk inside that will be filled in with<br> >     -- the length of the list once that's been determined. This works<br> >     -- efficiently (in one pass) because TH.Type is rather lazy.<br> >     (res, n) = foldl' (\(acc, !k) ty -> ([t| $acc $ty |], k + 1))<br> >                       (tupleT n, 0)<br> >                       ts<br> > <br> > I strongly suspect this is quite fast enough in practice, but it's a<br> > bit annoying that it won't participate in list fusion; tupT (map f xs)<br> > will (lazily) generate an intermediate list. I wasn't able to convince<br> > GHC to fuse it, short of a custom rewrite rule or two (tupT (build f)<br> > = ..., tupT (augment f r = ...). Does anyone know if it's possible?<br> <br> Can you say why it would not fuse? It seems it could, if tupT inlines,<br> and then you have foldl' applied to (map f xs), and at this point I<br> would hope that fusion kicks in.<br> <br> Cheers,<br> Joachim<br> <br> -- <br> Joachim Breitner<br>   <a href="mailto:mail@joachim-breitner.de" rel="noreferrer noreferrer" target="_blank">mail@joachim-breitner.de</a><br>   <a href="http://www.joachim-breitner.de/" rel="noreferrer noreferrer noreferrer" target="_blank">http://www.joachim-breitner.de/</a><br> <br> _______________________________________________<br> Haskell-Cafe mailing list<br> To (un)subscribe, modify options or view archives go to:<br> <a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe" rel="noreferrer noreferrer noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe</a><br> Only members subscribed via the mailman list are allowed to post.
       </blockquote>
      </div>
     </div>
    </div>
   </blockquote>
  </div>
 </div>
</blockquote></div></div></div>