Extra rules for empty lists will make the operations
work also on
finite-length inputs (polynomials)
and allow coerced scalars to be finite series.
Reference:
M. D. McIlroy, The music of streams (.ps.gz),
Information Processing Letters 77 (2001) 189-195.
series f = f : repeat 0 fromInteger c = series(fromInteger c) -- promote constants
negate (f:ft) = -f : -ft
(f:ft) + (g:gt) = f+g : ft+gt
(f:ft) * gs@(g:gt) = f*g : ft*gs + series(f)*gt
(f:ft) / (g:gt) = qs where qs = f/g : series(1/g)*(ft-qs*gt)
(f:ft) # gs@(0:gt) = f : gt*(ft#gs)
revert (0:ft) = rs where rs = 0 : 1/(ft#rs)
int fs = 0 : zipWith (/) fs [1..] -- integral from 0 to x
diff (_:ft) = zipWith (*) ft [1..] -- type (Num a,Enum a)=>[a]->[a]
tans = revert(int(1/(1:0:1)))From the usual differential relations between sine and cosine follows code
sins = int coss coss = 1 - int sinsWhen the operations are generalized to keep polynomials finite, the coefficients
pascal = 1/(1 - [[0],[1,1]])
Extensions to handle polynomials make a
practical package, doubled in size,
not as pretty, but much faster and capable of feats like pascal.
To see the dramatic speedup,
try a bigger test like take 20 tans.
Why is finite more complicated than infinite? The end must be detected, if nothing else.
Aug 2007. Text, but not code, trivially modified.
Sep 2007. Misprint in definition of sins corrected; OK in the complete packages.
Explanation page and Pascal's triangle added. Minor text modifications.
Mar 2008. Tweak the introduction.
Apr 2008.
Link code to explanations.
Change certain hyphens to minus signs.
Explain and fix
Enum nuisance.
Jul 2008. Trivial text edits.
Sep 2009. Mention operator (^^).
Shortcut multiplication by 0 in practical package.
Oct 2009. Mention recip.
Apr 2012. Page translated to Romanian by Alexandra Seremina.
Mar 2013. Correct a typo in explanations.