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
    print $ taylor (read x) (read tol)

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.