I am trying to define a function that accepts a point (x,y) as input, and returns an infinite list corresponding to recursively calling
P = (u^2 − v^2 + x, 2uv + y)
The initial values of u and v are both 0.
The first call would be
P = (0^2 - 0^2 + 1, 2(0)(0) + 2) = (1,2)
Then that resulting tuple (1,2) would be the next values for u and v, so then it would be
P = (1^2 - 2^2 + 1, 2(1)(2) + 2) = (-2,6)
and so on.
I'm trying to figure out how to code this in Haskell. This is what I have so far:
o :: Num a =>(a,a) -> [(a,a)]
o (x,y) = [(a,b)| (a,b)<- [p(x,y)(x,y)]]
where p(x,y)(u,v) = ((u^2)-(v^2)+x,(2*u*v)+y)
I'm really not sure how to make this work. Any help would be appreciated!
You want:
[(u, v)]
with the head of this list equal(0, 0)
map
this list with the function\(u, v) -> (u^2 - v^2 + x, 2 * u * v + y)
, appending results of this function to the list.We can write this function as described:
Let's first ignore the exact question you have, and focus on getting the loop working. What you want, essentially, is to have something that takes some initial value
iv
(namely,(0, 0)
for(u, v)
), and returns the listfor some function
f
(constructed from yourp
and(x, y)
). Moreover, you want the result to reuse the previously computed elements of the list. If I would write a function myself that does this, it might looke like this (but maybe with some different names):But, of course, I would first look if a function with that type exists. It does: it's called
Data.List.iterate
. The only thing it does wrong is the first element of the list will beiv
, but that can be easily fixed by usingtail
(which is fine here: as long as your iteration function terminates,iterate
will always generate an infinite list).Let's now get back to your case. We established that it'll generally look like this:
As you indicated, the initial value of
(u, v)
is(0, 0)
, so that's what our definition ofiv
will be.f
now has to callp
with the(x, y)
fromo
's argument and the(u, v)
for that iteration:It's as simple as that: the
(x, y)
fromo
's definition is actually in scope in thewhere
-clause. You could even decide to mergef
andp
, and end up withAlso, may I suggest that you use
Data.Complex
for your application? This makes the constraints ona
a bit stricter (you needRealFloat a
, because ofNum.signum
), but in my opinion, it makes your code much easier to read: