Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 用Monad.Writer计算正弦函数_Haskell - Fatal编程技术网

Haskell 用Monad.Writer计算正弦函数

Haskell 用Monad.Writer计算正弦函数,haskell,Haskell,我用泰勒级数实现了sin函数。我在其中使用了map如下: sin' x = sum $ map (\n -> term x n) [0..50] where term x n = (x^pw / fromIntegral (fact pw))*(-1)^n pw = 2*n+1 但是如何在编写器日志中«保存»中间值(使用告诉)?我必须使用递归调用重写我的函数吗?我不知道如何在没有递归的情况下获得这些中间值,我不确定这是否是您想要的,但这是我能想到的在这里使用W

我用泰勒级数实现了sin函数。我在其中使用了
map
如下:

sin' x = sum $ map (\n -> term x n) [0..50]
    where term x n = (x^pw / fromIntegral (fact pw))*(-1)^n
          pw = 2*n+1

但是如何在编写器日志中«保存»中间值(使用
告诉
)?我必须使用递归调用重写我的函数吗?我不知道如何在没有递归的情况下获得这些中间值,我不确定这是否是您想要的,但这是我能想到的在这里使用
Writer
的唯一有用的方法

这样一个天真的泰勒级数实现的问题是,你会一遍又一遍地计算幂和阶乘,而实际上,以增量的方式进行计算会更有效。反复出现的情况如下:

      term' x pw ≡ - x^2 * term' x (pw-2) / fromIntegral pw
当然,您不希望为每个求和重新计算,而是希望在进行时对这些项求和。这就是作家的作用所在;我们当然需要
Writer(总和加倍)

procTerms::Double->Int->Writer(Sum Double)Double
procTerms x 1=告诉(总和x)>>返回x
procTerms x pw=do

纽特姆:你到底想存什么?
项x n的每个值?另外,您使用的不是列表理解,而是
map
,它可以更简单地写为
sum$map(term x)[0..50]
。如果是列表理解,它就像
sum[term x n | n老实说,如果你只想要中间值,我会使用
scanl
而不是复杂的
Writer
东西。如果你想要所有的术语,不要求和。
      procTerms :: Double -> Int -> Writer (Sum Double) Double
      procTerms x 1 = tell (Sum x) >> return x
      procTerms x pw = do
         newterm <- fmap (* (- x^2 / fromIntegral pw)) $ term' x (pw-2)
         tell $ Sum newterm
         return newterm