[clean-list] Strict lists kill me...
Jerzy Karczmarczuk
karczma@info.unicaen.fr
Mon, 01 Dec 2003 09:48:52 +0100
Gentle gurus.
I wrote a short program which generates co-recursively a stream
representing the sampled sine function, using the identity:
sin(x+2h) = 2 sin(x+h)*cos(h) - sin(x)
Of course, the algorithm shown below being co-recursive needs spine
laziness. But I don't need - I think... - to have the head laziness.
So, I wrote three identical versions using [], [!] and [#]. Here it is:
// =============================================
module litest
import StdEnv, StdStrictLists, StdOverloadedList
class (*>) infixr 7 t :: !Real (t Real) -> (t Real)
instance *> [] where
(*>) x l = map (\s -> x*s) l
instance *> [!] where
(*>) x l = Map (\s -> x*s) l
instance *> [#] where
(*>) x l = Map (\s -> x*s) l
ZipWith op [|a:as] [|b:bs] = [|(op a b) : ZipWith op as bs]
ZipWith op as bs = [|]
instance - [#Real]
where
(-) l1 l2 = ZipWith (-) l1 l2
instance - [!Real]
where
(-) l1 l2 = ZipWith (-) l1 l2
instance - [Real]
where
(-) l1 l2 = ZipWith (-) l1 l2
oscilu =: (z,v,r) where
z =: [# 0.0 : v]
v =: [# sin 0.01 : r]
r =: (2.0*cos 0.01)*>v - z
oscils =: (z,v,r) where
z =: [! 0.0 : v]
v =: [! sin 0.01 : r]
r =: (2.0*cos 0.01)*>v - z
oscill =: (z,v,r) where
z =: [0.0 : v]
v =: [sin 0.01 : r]
r =: (2.0*cos 0.01)*>v - z
Start = let (a,b,c) = oscill
in (Take 10 a, Take 10 b, Take 10 c)
// ====================================================
The operator (*>) multiplies a list by a scalar. It, and the 2-mapped (-)
are duly overloaded. The result is the list, its tail, and its tail_tail.
Yes, it seems silly, first element should suffice. But now comes the issue.
The program - as it is - produces the expected result.
Change oscill into oscils in Start. Ready to guess the result?
Here it is:
([],[.0099998333416666],[])
Nice, isn't it, especially the tail of the empty list...
============================================================================
Now, change oscils into oscilu. Ready for another guess?
(Run Time Warning: cycle in spine detected
***************************************************************************
This is all. I suspect that this might be a bug somewhere in the treatment
of not-entirely-lazy lists. Perhaps the translation between (:) and cons,
cons_u or whatever is imperfect. Perhaps the overloading plays some dirty
tricks.
Or, perhaps I simply I did something illegal in my coding, in this case
I would very humbly suggest to introduce some appropriate caveats into the
documentation...
Thank you.
Jerzy Karczmarczuk
Caen, France