我第一次玩Haskell。
我创建的函数首先返回足够精确的结果。它按预期工作,但我正在使用发电机。如何在此任务中更换发电机?
integrateWithPrecision precision =
(take 1 $ preciseIntegrals precision) !! 0
preciseIntegrals :: Double -> [Double]
preciseIntegrals precision =
[
integrate (2 ^ power) pi | power <- [0..],
enoughPowerForPrecision power precision
]
答案 0 :(得分:3)
您可以使用the beautiful until
function。这是:
-- | @'until' p f@ yields the result of applying @f@ until @p@ holds.
until :: (a -> Bool) -> (a -> a) -> a -> a
until p f x | p x = x
| otherwise = until p f (f x)
所以,你可以这样编写你的函数:
integrateWithPrecision precision = integrate (2 ^ pow) pi
where
pow = until done succ 0
done pow = enoughPowerForPrecision pow precision
在您的情况下,您执行所有迭代,然后只计算一次结果。但是,即使您需要在每个步骤计算结果,until
也很有用 - 只需使用(iter, result)
元组,然后在result
处最后提取snd
。< / p>
答案 1 :(得分:1)
功能
\xs -> take 1 xs !! 0
称为head
head [] = error "Cannot take head of empty list"
head (x:xs) = x
它的使用有些不安全,如图所示,如果你把它传递给空列表就会抛出一个错误,但在这种情况下你可以确定你的列表是非空的,这很好。
此外,我们倾向于不在Haskell中称这些“生成器”,因为它们不是一种特殊形式,而是懒惰评估的简单结果。在这种情况下,preciseIntegrals
被称为“列表理解”,而[0..]
只不过是一个懒惰的列表。
答案 2 :(得分:1)
似乎你想要检查越来越高的权力,直到你得到满足要求的权力。这是你可以做的:首先你定义一个函数来获得足够的能量,然后你用它集成。
find
获取满足条件的列表的第一个元素 - 比如足够强大!然后我们需要fromJust
来获取实际值。请注意,几乎所有fromJust
都是可怕的想法。但是,在这种情况下,列表是无限的,所以在fromJust
能够使程序崩溃之前很久就会遇到无限循环的麻烦。
enoughPower :: Double -> Int
enoughPower precision =
fromJust $ find (flip enoughPowerForPrecision precision) [0..]
preciseIntegrals :: Double -> Double
preciseIntegrals precision = integrate (2^(enoughPower precision)) pi