# A newbie's proud first code

**Adrian Hey
**
ahey@iee.org

*Mon, 5 Nov 2001 09:53:37 +0000*

On Monday 05 November 2001 7:27 am, Luke Maurer wrote:
>* -- 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
*>* interval
*>* -- 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
*>* supply
*>* -- 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)
*>*
*>* 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?
*
Well, I'm no expert in Haskell style, but some might say it's better style
to lift out the constants f' and dt as free variables in a local definition
of euler' ..
euler :: (Num a) => (a -> a -> a) -> a -> (a -> [a])
euler f' dt = euler' 0
where euler' t f = let fnext = f + dt * (f' f t)
tnext = t + dt
in f : euler' tnext fnext
I think that works. I'm not sure if or why that's better but Haskeller's
seem to do this kind of thing a lot. It's good for looking smart and
confusing newbies if nothing else :-)
Regards
--
Adrian Hey