我有一些代码可以反复接近一个解决方案,它实际上做的并不重要,但它通过改变mg(m猜测,从4.0开始因为我"知道"它应该在球场中)而对r'== rt有效. .
solve_m f ar st qt = solve_m' f ar st qt 4.0
where
solve_m' f ar st qt mg
| rd > precis = f' (mg - sf)
| rd < (-precis) = f' (mg + sf)
| otherwise = mg
where
f' = solve_m' f ar st qt
rt = st + qt
r' = f st ar mg
rd = rt - r'
sf = abs(rd)
Run Code Online (Sandbox Code Playgroud)
我想要做的是计算周期数,我知道正确的方法是使用State monad,但是最优雅的方法是将put/get放入这样的函数中?让f'成为阻止?或者只是添加一个计数器solve_m'并返回(counter,mg)?
谢谢!
编辑:这似乎基本上是我想要的,没有必要的Monads:
solve_m f ar st qt = (last (series), length(series))
where
series = takeWhile termPred (iterate solve_m' 4.0)
termPred m' = (abs (rt - (f st ar m'))) > precis
rt = st + qt
solve_m' mg
| rt > r' = (mg - sf)
| rt < r' = (mg + sf)
where
r' = f st ar mg
rd = rt - r'
sf = abs(rd)
Run Code Online (Sandbox Code Playgroud)
仍然看起来有点凌乱(重复的代码),但我会整理它...这将在我将取代的代码的迭代的1/10000中获得可接受的结果!
在不查看算法的情况下,执行此操作的一般方法是从迭代算法中划分终止条件:
terminationPred :: a -> Bool
algorithm :: a -> a
Run Code Online (Sandbox Code Playgroud)
然后使用iterate和takeWhile:
itermediates = takeWhile (not . terminationPred) . iterate algorithm
resultAndRecursions :: a -> (a, Int)
resultAndRecursions a = (last (intermediates a), length (intermediates a) - 1)
-- you'd want to make your own safe function here, not use last and length
Run Code Online (Sandbox Code Playgroud)
或展开:
intermediates = unfoldr op
where
op a | terminationPred a = Nothing
| otherwise = let a' = algorithm a
in Just (a', a')
Run Code Online (Sandbox Code Playgroud)
编辑:还注意到这两个中间体略有不同,因为第一个维持基本情况(输入a,因此- 1),而第二个不存在,因此在互补中会有微小的差异resultAndRecursions.
| 归档时间: |
|
| 查看次数: |
1870 次 |
| 最近记录: |