You can do symbolic algebra on symbolic function definitions. What's interesting about this stuff is that it works for "real" functions - plain Haskell functions that we can't inspect the definition of, just call in the normal way (there's no macros or monkeypatching or anything like that going on). It's like being able to use numerical methods but still somehow solve everything exactly.