
The question I asked is about how to type the differentiation function. Whether the function is correct is a different question, which I'm happy to talk about; but understand that it's just an example I was playing with. Luke Palmer wrote:
Oh, I think I totally missed the point. I missed the word "simple".
No, I don't think you did miss the point in terms of what the code is doing. I said simple because I'm not thinking about vector-valued or multidimensional functions, partial derivatives, gradients, etc. This is on functions from numbers to numbers, where "numbers" are defined by the three type classes Num, Fractional, and Floating. I (probably incorrectly) used "simple" to say so.
I think the problem is that a function of type Num a => a -> a can be any function whatsoever, it does not have to be a simple combination of operators (it could, for example, use show, do a string transformation, and then read the result).
Well, no you couldn't read the result directly, since Num is a subclass of only Eq and Show. You could read as an integer and then use fromInteger to do so, but that the code I wrote would treat the result as a constant, so the derivative would always be reported as zero. I realize this is strictly an incorrect implementation of fromInteger (and fromRational in the Fractional class), but at the same time, there is no correct implementation. For functions that refrain from using fromInteger or fromRational except on constants, and modulo any coding errors (as I said, I didn't implement this cautiously), this should give you the correct derivative for any function when the derivative exists. What it doesn't do is evaluate properly to bottom/NaN when the derivative fails to exist. Part of that is my lazy lack of interest in writing the code correctly. For example, log (-1) is NaN, but my code will give you (-1) as the derivative, suggesting (incorrectly, of course) that log is undefined but still differentiable at that point. But another part of it is endemic; for example, f x = if signum x == (-1) then (-x) else x redefines the absolute value function, which is not differentiable at 0, but this implementation will claim f'(0) = 1, and there's no obvious way to avoid it without changing a lot. -- Chris Smith