I’ve been dabbling with haskell in the recent days. My first semi-serious attempt to some code was inspired by a prompt at programming praxis.
What I concocted should ashame any veteran haskell programmer (if you are and have stumbled on this by accident feel free to point me in the right direction;-)):

```import System.Environment

taylor :: Double -> Double -> Double
taylor x tol = reduce1 (x - fromIntegral(truncate(x / (2*pi)))*(2*pi)) tol

reduce1 :: Double-> Double -> Double
reduce1 x tol
| x < 0 = (-reduce2 (-x) tol)
| otherwise = reduce2 x tol

reduce2 :: Double -> Double -> Double
reduce2 x tol
| x <= pi/2 = sumTaylor x tol
| x <= pi = sumTaylor (pi - x) tol
| x <= 3*pi/2 = (-sumTaylor (x - pi) tol)
| otherwise = (-sumTaylor (2*pi - x) tol)

sumTaylor :: Double -> Double -> Double
sumTaylor x tol = checkdelta (scanl sumOdd (0,1,1,-1) [1..]) tol
where sumOdd (p,n,d,s) el
| even el = (p-s*n/d,n*x,d*fromIntegral el,-s)
| otherwise = (p,n*x,d*fromIntegral el,s)

checkdelta :: [(Double,Double,Double,Double)] -> Double -> Double
checkdelta (a:b:c:xs) tol = if abs ( first4 a - first4 c ) < tol then first4 c else checkdelta (c:xs) tol
checkdelta [] _ = 0

first4 :: (Double,Double,Double,Double) -> Double
first4 (a,b,c,d) = a

main :: IO ()
main = do
(x:tol:[]) <- getArgs
```

I was curious to see how this would fare against a C equivalent, so I quickly typed the following:

```#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#define max_iter 100

/*
* Compute the taylor sum x-x**3/3!+x**5/5!+ ...
* Stop if the difference between 2 consecutive terms is minor than a given
* tolerance or if it doesn't converge after 100 iterations.
*
*/

double sum(const double x, const double tol) {

double y, old_y, num, den, sign;
int i;

y = 0.0;
num = 1.0;
den = 1.0;
sign = 1.0;
old_y = 100.0;

for ( i=1; i<max_iter; i++ ) {
if (!(i & 1)) {
y += sign*num/den;
sign = -sign;
if(fabs(y-old_y)<tol) return y;
old_y = y;
}
num *= x;
den *= (double)i;
}
return NAN;
}

int main(int argc, char **argv) {

double x, tol, pi, y;
int i, sign = 0;

if (argc<2) {
printf("Requires at least a numeric argument\n");
return -1;
}

pi = atan(1.0)*4.0;
x = strtod(argv[1], NULL);

if (argc==3) {
tol = strtod(argv[2], NULL);
} else {
tol = 1.0e-9;
}

//Only compute for positive x (since sin(x)=-sin(-x))
if ( x < 0 ) {
x = -x;
sign = 1;
}

//Limit x to the 0-2pi range (sine is periodic with period=2pi
x -= floor(x/(2*pi)) * (2*pi);

//Only compute in the first quadrant and use symmetries
if ( x <= pi/2 ) {
y = sum(x, tol);
} else if ( x <= pi) {
y = sum(pi-x, tol);
} else if ( x <= 3*pi/2 ) {
y = -sum(x-pi, tol);
} else {
y = -sum(2*pi-x, tol);
}

if (sign) y = -y;

printf("%.16f\n", y);

return 0;
}
```

Code size wise the haskell one is indeed more compact (and I think there is still room for improvement), however the size of the executable is amazingly different. With default compiler settings for gcc and gch the C program is 8.2 kB and the haskell one 1007 KB!? I wonder what is all that overhead …

Also, performance wise the C code is about 100% faster than the haskell one (but that I expected).

Well, its not really a fair comparison, the problem is indeed more tailored to imperative programming.