`max` and `pow` can either run eagerly (as functions) or they can run lazily and allow for interesting lazy things. For example, if you put them into a lazy object graph, you could perform optimizing measures.
Check this out:
1/2 * 2/1 == 1
Would you actually calculate each intermediate result of that expression? Or would you just reduce the fraction? Should 1/2 be exectuted and yield 0.5 immediately, or could it be useful to have them hang around some more? FP vs. OOP is the difference of understanding / as "Please divide 1 by 2 now" vs "That IS a fraction; one half".
> There is no need to force every peg into a coalgebra hole.
True, but how awesome would it be if I did that anyway :D
Regarding `max` and `pow` as objects: Yegor Bugayenko argues for a similar thing in his book "Elegant Objects".
The main difference is that algebras are more natural in FP and coalgebras in OOP, but they can mostly do the same things, just a bit differently. Actually you can also do algebras in OOP as well (visitor pattern) and coalgebras is FP.
Basically my point was that you should use the simplest abstraction that gets the job done. Even if you implemented max and pow as objects, for your specific use case, you would probably just call the pure functions inside.
Thank you for the book recommendation.