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
http://lpaste.net/2416758997739634688 )
When I define
scanr f b = reverse . scanl (flip f) b . reverse
I get this:
scanr1
scanr1 = \ @ a_akP _ eta_Xb -> eta_Xb
scanr
scanr =
\ @ a_akP @ a1_akQ f_ah8 b_ah9 eta_B1 ->
letrec {
go_amb
go_amb =
\ ds_amc eta1_Xa eta2_B2 eta3_Xc ->
case ds_amc of _ {
[] -> eta1_Xa eta2_B2 eta3_Xc;
: y_amh ys_ami ->
go_amb
ys_ami
(\ x_an9 eta4_Xj ->
let {
b'_ana
b'_ana = f_ah8 y_amh x_an9 } in
eta1_Xa b'_ana (: b'_ana eta4_Xj))
eta2_B2
eta3_Xc
}; } in
go_amb eta_B1 (scanr1) b_ah9 (: b_ah9 ([]))
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:
scanr1
scanr1 = \ @ a_akP _ eta_Xb -> eta_Xb
scanr
scanr =
\ @ a_akP @ a1_akQ f_ah8 b_ah9 eta_B1 ->