instance Semigroup (Endo a) where
...
stimes = stimesMonoid
stimesMonoid produces a balanced tree. I guess this enhances sharing within the resulting function (if it's realized as a closure), but I'm wondering if it's really a good idea, especially when the argument is small.
Here's a simpler option to play with:
stimes n _ | n < 0 = error "Cannot apply a function a negative number of times."
stimes n0 e = go (fromIntegral n0)
where
go 0 = mempty
go n = e <> go (n - 1 :: Word64)
Another possibility might be to make a tree that only leans to the right. That would get immediate access to the leftmost (most important) nodes while maintaining sharing for the large case.
Currently,
stimesMonoid
produces a balanced tree. I guess this enhances sharing within the resulting function (if it's realized as a closure), but I'm wondering if it's really a good idea, especially when the argument is small.Here's a simpler option to play with:
Another possibility might be to make a tree that only leans to the right. That would get immediate access to the leftmost (most important) nodes while maintaining sharing for the large case.