Confused about types

I thought I was doing ok with haskell until I tried to program in
it. :/ I figured the first thing to tackle was something easy
so I hacked up newton's method. Worked great for Double's. Then
I figured I would extend it to work with different types of
Fractionals. What a pain. I finally got that working for Floats
and Rationals but I'm drawing a blank on Complex.
I've got:

Note that you can't pattern match to make special cases for handling particular types, only against data constructors in the specific type which your function accepts as input. You need a typeclass if you want to have a function which acts differently at different types. As you might have realised abs is somewhat ineffective for comparing the magnitudes of numbers which aren't already in Ord, as it will produce a value of the same type. The main trouble here is that abs :: (Num a) => a -> a and doesn't help to order the complex numbers. On the other hand, there is magnitude :: (RealFloat a) => Complex a -> a which will take your Complex Double and give you back a Double, for instance, and Double will be ordered, which is exactly what you want. The quickest way to solve this problem is to just make a typeclass for the Newton's method functions, and put them in it, and change the implementation for the Complex instance. You might also consider making a class for a general norm operation, but this would pretty much necessarily be a multiparameter typeclass, and you'd likely want to use functional dependencies, so that the result type would be determined by the input type. hope this helps, - Cale

Well ick. It makes sense (not that I can do it yet but I understand what you are saying). I'll try both approaches since this is all about learning the language. I can throw in the "closeness" concept to norm as well. Without symbolic computation hitting an irrational value will take more time to get a numeric answer than I'm willing to spend. Thanks for pointing the way, -ljr Cale Gibbard wrote:
Note that you can't pattern match to make special cases for handling particular types, only against data constructors in the specific type which your function accepts as input.
You need a typeclass if you want to have a function which acts differently at different types. As you might have realised abs is somewhat ineffective for comparing the magnitudes of numbers which aren't already in Ord, as it will produce a value of the same type.
The main trouble here is that abs :: (Num a) => a -> a and doesn't help to order the complex numbers. On the other hand, there is magnitude :: (RealFloat a) => Complex a -> a which will take your Complex Double and give you back a Double, for instance, and Double will be ordered, which is exactly what you want.
The quickest way to solve this problem is to just make a typeclass for the Newton's method functions, and put them in it, and change the implementation for the Complex instance. You might also consider making a class for a general norm operation, but this would pretty much necessarily be a multiparameter typeclass, and you'd likely want to use functional dependencies, so that the result type would be determined by the input type.
hope this helps, - Cale
--
Lanny Ripple

On Fri, 30 Sep 2005, Lanny Ripple wrote:
newton_h, next_x_h, dy_h :: (Fractional a, Ord a) => (a -> a) -> a -> a -> a newton_h f x h = until ((<= h) . abs . f) (next_x_h f h) x
If this shall be more than a disposable example, I suggest to separate the Newton iteration from the abort of the iteration. Newton's method could return a list of the interim results, a sequence in the mathematical sense. newton :: Fractional a => (a -> (a,a)) -> a -> [a] The function would compute both the value and the derivative, e.g. (\x -> (sin x, cos x)) Then you can easily apply various implementations of a numeric limit. limit :: [a] -> a The most simple implementation is certainly: limit = (!!100) Eventually a function numericDiff :: Fractional a => a -> (a -> a) -> (a -> (a,a)) could extend a function by some difference quotient.

On Wed, 05 Oct 2005, Henning Thielemann
If this shall be more than a disposable example, I suggest to separate the Newton iteration from the abort of the iteration.
There is a related example, demonstrating this technique, in "Why Functional Programming Matters": http://www.cs.chalmers.se/~rjmh/Papers/whyfp.html -- /NAD

Thanks for the feedback. It was basically a disposable example of something to learn the language with. All the examples in all the tutorials are toy problems and all the systems put forward as having been written in haskell are huge. A collection of medium solutions that folks could use to see how someone who knows the language would solve the problem would go a long way to bridge the gap. -ljr Henning Thielemann wrote:
On Fri, 30 Sep 2005, Lanny Ripple wrote:
newton_h, next_x_h, dy_h :: (Fractional a, Ord a) => (a -> a) -> a -> a -> a newton_h f x h = until ((<= h) . abs . f) (next_x_h f h) x
If this shall be more than a disposable example, I suggest to separate the Newton iteration from the abort of the iteration. Newton's method could return a list of the interim results, a sequence in the mathematical sense. newton :: Fractional a => (a -> (a,a)) -> a -> [a] The function would compute both the value and the derivative, e.g. (\x -> (sin x, cos x))
Then you can easily apply various implementations of a numeric limit. limit :: [a] -> a The most simple implementation is certainly: limit = (!!100)
Eventually a function numericDiff :: Fractional a => a -> (a -> a) -> (a -> (a,a)) could extend a function by some difference quotient.
--
Lanny Ripple
participants (4)
-
Cale Gibbard
-
Henning Thielemann
-
Lanny Ripple
-
Nils Anders Danielsson