A newbie's proud first code

Luke Maurer jyrinx@mindspring.com
Sun, 4 Nov 2001 23:27:15 -0800

Hi! I'm glad to have run accross Haskell, as a project I've been toying with
in my mind seems very well-suited for this. It involves the numeric solution
of differential equations. I'm thrilled to see how easy this is, as shown in
my first little code snippet:


-- Euler's method for solution of first-order differential equations
-- In function arguments, the initial value problem under consideration is:

-- df/dt = f'(f, t)
-- f(0) = f0

-- The euler function returns an infinite list of the values at each
-- of length dt of the solution.
euler                   :: (Num a) => (a -> a -> a) -> a -> a -> [a]
euler f' dt f0          = euler' f' dt f0 0 -- t "defaults" to 0

-- This function does the actual work, sparing the user from having to
-- a value for t (which should always be 0 in the initial call, anyway)
euler'                  :: (Num a) => (a -> a -> a) -> a -> a -> a -> [a]
euler' f' dt f t        = f : euler' f' dt fnext (t + dt)
        where fnext     = f + dt * (f' f t)


(Only three lines of actual code (not counting declarations)! Consider me a
convert :-) Yes, you could do it like this in Lisp, I'm sure, but this is so
much more succinct and expressive ... and Lisp can't do this cool infinite
list stuff, can it?)

My only issue (and it is nitpicky) is that I don't really like having to
declare an extra function (euler') in the same scope as euler. I tried
playing with where clauses or let expressions, but I couldn't find a way to
make GHC happy without introducing a bunch of extra variables (since I'd
need new versions of the arguments to euler; in euler', I just used the same
names. Also, nested "where" doesn't work as I'd like it to.) Is there, in
fact, a more concise way to express what I'm doing?

Would anyone like to comment on my style (or lack thereof), idiom, etc., so
I can squelch any bad habits before they start :-) ? Thanks!

jyrinx_list at mindspring dot com