Ah, that makes sense, thanks.
Looking at this again today, there’s actually a massive mistake. The test to check that functools_reduce and recursive_reduce match was wrong, it was just testing to see that recursive_reduce and recursive_reduce were equal. Fixing that, I realised that the resulting matrix explodes, which makes the test a little difficult, so have to scale by sqrt of M to keep approximately unit variance.