<div dir="ltr"><div><div><div><div><div>Aside from anything having to do with the foldrW/buildW stuff, I decided to try a little experiment using fusing scanl and reverse (implementations at <a href="http://lpaste.net/2416758997739634688" target="_blank">http://lpaste.net/2416758997739634688</a> )<br><br></div>When I define<br><br>scanr f b = reverse . scanl (flip f) b . reverse<br><br></div>I get this:<br><br>scanr1<br>scanr1 = \ @ a_akP _ eta_Xb -> eta_Xb<br><br>scanr<br>scanr =<br>  \ @ a_akP @ a1_akQ f_ah8 b_ah9 eta_B1 -><br>    letrec {<br>      go_amb<br>      go_amb =<br>        \ ds_amc eta1_Xa eta2_B2 eta3_Xc -><br>          case ds_amc of _ {<br>            [] -> eta1_Xa eta2_B2 eta3_Xc;<br>            : y_amh ys_ami -><br>              go_amb<br>                ys_ami<br>                (\ x_an9 eta4_Xj -><br>                   let {<br>                     b'_ana<br>                     b'_ana = f_ah8 y_amh x_an9 } in<br>                   eta1_Xa b'_ana (: b'_ana eta4_Xj))<br>                eta2_B2<br>                eta3_Xc<br>          }; } in<br>    go_amb eta_B1 (scanr1) b_ah9 (: b_ah9 ([]))<br><br></div>go_amb takes four arguments, two of which, eta2_B2 and eta3_Xc, are static. What makes this seem particularly silly is that we already have all the structure we need to get rid of them—all that remains is to actually delete them and replace them with the values they take:<br><br>scanr1<br>scanr1 = \ @ a_akP _ eta_Xb -> eta_Xb<br><br>scanr<br>scanr =<br>  \ @ a_akP @ a1_akQ f_ah8 b_ah9 eta_B1 -><br></div>    let {<br></div><div>      listend<br></div>      listend = : b_ah9 ([])} in<br><div><div><div><div>    letrec {<br>      go_amb<br>      go_amb =<br>        \ ds_amc eta1_Xa  -><br>          case ds_amc of _ {<br>            [] -> eta1_Xa b_ah9 listend;<br>            : y_amh ys_ami -><br>              go_amb<br>                ys_ami<br>                (\ x_an9 eta4_Xj -><br>                   let {<br>                     b'_ana<br>                     b'_ana = f_ah8 y_amh x_an9 } in<br>                   eta1_Xa b'_ana (: b'_ana eta4_Xj))<br>          }; } in<br>    go_amb eta_B1 (scanr1)<br><br></div><div>Now I certainly wouldn't claim this is particularly *good* code, but it seems significantly more reasonable than before.<br><br></div><div>If I were to try to find a way to get rid of these things, should I try hacking on the static argument transformation, or would it fit better in the simplifier, or somewhere else?<br></div><div><br></div><div>David<br></div></div></div></div></div>