マクローリン展開によるsin関数

30分プログラム、その622。http://gauc.no-ip.org/awk-users-jp/blis.cgi/DoukakuAWK_188にインスパイアされて、sin関数を書いてみます。
マクローリン展開をそのまま実装すればいいんだろ、簡単簡単』と思ってら、わりと時間がかかってしまった。IntじゃなくてIntegerを使うべきなのに気がつくのに時間がかかったからなぁ。

使い方

*Main> mySin 0
0.0
*Main> mySin (pi/2)
0.9999999999939768

ソースコード

import Data.List
fact :: Integer -> Integer
f    :: Floating a => Integer -> a -> a

fact n = product [1..n]

f n x = (numer / denom) * x'
    where float n = fromInteger $ toInteger n
          numer = (-1) ** (float n)
          denom = float $ fact $ 2 * n + 1
          x'    =  x ** (float $ 2 * n + 1)

sinStream x = scanl1 (+) [f n x | n <- [0..]]

mySin x = let xs = sinStream x in
          case find (\(current,prev)-> abs (current - prev) < 1e-8) $ zip (tail xs) xs of
            Nothing ->
                error "must not happen"
            Just (x,_) ->
                x