module Polynomial (
   T, fromScalar, add, sub, neg, scale, mul,
   differentiate, progression,
   ) where


type T a = [a]


fromScalar :: a -> [a]
fromScalar :: forall a. a -> [a]
fromScalar = (forall a. a -> [a] -> [a]
:[])

-- | add two polynomials or series
add :: Num a => [a] -> [a] -> [a]
{- zipWith (+) would cut the resulting list
   to the length of the shorter operand -}
add :: forall a. Num a => [a] -> [a] -> [a]
add [] [a]
ys = [a]
ys
add [a]
xs [] = [a]
xs
add (a
x:[a]
xs) (a
y:[a]
ys) = a
xforall a. Num a => a -> a -> a
+a
y forall a. a -> [a] -> [a]
: forall a. Num a => [a] -> [a] -> [a]
add [a]
xs [a]
ys

-- | subtract two polynomials or series
sub :: Num a => [a] -> [a] -> [a]
sub :: forall a. Num a => [a] -> [a] -> [a]
sub [] [a]
ys = forall a b. (a -> b) -> [a] -> [b]
map forall a. Num a => a -> a
negate [a]
ys
sub [a]
xs [] = [a]
xs
sub (a
x:[a]
xs) (a
y:[a]
ys) = a
xforall a. Num a => a -> a -> a
-a
y forall a. a -> [a] -> [a]
: forall a. Num a => [a] -> [a] -> [a]
sub [a]
xs [a]
ys

neg :: Num a => [a] -> [a]
neg :: forall a. Num a => [a] -> [a]
neg = forall a b. (a -> b) -> [a] -> [b]
map forall a. Num a => a -> a
negate

-- | scale a polynomial or series by a factor
scale :: Num a => a -> [a] -> [a]
scale :: forall a. Num a => a -> [a] -> [a]
scale a
s = forall a b. (a -> b) -> [a] -> [b]
map (a
sforall a. Num a => a -> a -> a
*)


-- | multiply two polynomials or series
mul :: Num a => [a] -> [a] -> [a]
{- prevent from generation of many zeros
   if the first operand is the empty list -}
mul :: forall a. Num a => [a] -> [a] -> [a]
mul [] = forall a b. a -> b -> a
const []
mul [a]
xs = forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (\a
y [a]
zs -> forall a. Num a => [a] -> [a] -> [a]
add (forall a. Num a => a -> [a] -> [a]
scale a
y [a]
xs) (a
0forall a. a -> [a] -> [a]
:[a]
zs)) []


progression :: Num a => [a]
progression :: forall a. Num a => [a]
progression = forall a. (a -> a) -> a -> [a]
iterate (a
1forall a. Num a => a -> a -> a
+) a
1


differentiate :: (Num a) => [a] -> [a]
differentiate :: forall a. Num a => [a] -> [a]
differentiate [a]
x = forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith forall a. Num a => a -> a -> a
(*) (forall a. [a] -> [a]
tail [a]
x) forall a. Num a => [a]
progression