gpt4 book ai didi

haskell - 将 "Why Functional Programming Matters"翻译成 Haskell

转载 作者:行者123 更新时间:2023-12-03 22:22:49 26 4
gpt4 key购买 nike

为了丰富文化和知识,我决定学习一点 Haskell。我一直在阅读Hughes' "Why Functional Programming Matters"并试图将其代码翻译成真正的 Haskell。我在下面附上了我的一些尝试(对于论文的数字部分;alpha-beta 算法更有趣,但我还必须从头开始编写一个游戏评估器!)。
在这一点上,它更像是对 Haskell 语法的练习,而不是其他任何东西。我已经做了一些简单的事情,比如翻译 repeat进入原生 Haskell iterate ,翻译一些使用大量括号的函数来进行函数组合(使它们在过程中更加无点)等。
但我的代码确实有效,我想知道它是否足够“Haskell-ish”。有哪位高手可以给我一些提示吗?

-- 4.1 Newton-Raphson square roots
next n x = (x + n/x)/2.0

-- -- this is "iterate::(a->a)->a->[a]"
-- repeat f a = a : iterate f (f a)

within eps (a:b:rest) =
if abs(a-b) <= eps
then b
else within eps (b:rest)

sqroot a0 eps n = within eps (iterate (next n) a0)

relative eps (a:b:rest) =
if abs(a-b) <= eps*abs(b)
then b
else relative eps (b:rest)

relativesqrt a0 eps n = relative eps (iterate (next n) a0)

-- 4.2 numerical differentiation

easydiff f x h = (f (x+h) - f x) / h

differentiate h0 f x = map (easydiff f x) (iterate (/2) h0)

-- diff1a h0 eps f x = within eps (differentiate h0 f x)
diff1 h0 eps f = within eps . differentiate h0 f

elimerror n (a:b:rest) = (b*(2**n)-a)/(2**n-1) : elimerror n (b:rest)

-- need fromIntegral to make a non-integer out of the Int which comes out of round
order (a:b:c:rest) = fromIntegral (round (logBase 2 ((a-c)/(b-c)-1)))

improve s = elimerror (order s) s

--diff2a h0 eps f x = within eps (improve (differentiate h0 f x))
diff2 h0 eps f = within eps . improve . differentiate h0 f

--super s = map second (iterate improve s) -- how can we make this point-free?
super :: (RealFrac t, Floating t) => [t] -> [t]
-- w/o this it wants to be [double]->[double]
super = map second . iterate improve

-- second (a:b:rest) = b
second = head . tail

diff3 h0 eps f = within eps . super . differentiate h0 f

-- 4.3 integration

easyintegrate f a b = (f a + f b)*(b-a)/2

-- addpair becomes (uncurry (+))

integrate f a b = integ f a b (f a) (f b)

integ f a b fa fb =
(fa+fb)*(b-a)/2 : map (uncurry (+)) (zip (integ f a m fa fm) (integ f m b fm fb))
where m = (a+b)/2
fm = f m

-- test: following should be about pi
approxpi eps = within eps (improve (integrate (\x -> 4/(1+x*x)) 0 1))
superpi eps = within eps (super (integrate (\x -> 4/(1+x*x)) 0 1))

-- is there any way to keep track of the number of iterations? state monad, but seems like a lot of work...\

最佳答案

4.1 Newton-Raphson 平方根

这两行

sqroot a0 eps n = within eps (iterate (next n) a0)
relativesqrt a0 eps n = relative eps (iterate (next n) a0)

几乎相同,因此您可以进一步抽象事物:
sqroot method a0 eps n = method eps (iterate (next n) a0)
relativesqrt = sqroot relative
withinsqrt = sqroot within

4.2 数值微分

我看不出拥有 h0 的意义。作为 differentiate 的参数函数,因为它只是 0 的起点限制顺序。 (在 Newton-Rhapson 案例中, a0 并非如此,起点可能很重要)。

我认为抽象出这个限制接近零的速率同样合适:
differentiate rate f x = map (easydiff f x) (iterate rate 1)

当然,两者都可以做到:
differentiate rate h0 f x = map (easydiff f x) (iterate rate h0)

无论如何,这是一个相当武断的决定。

4.2 集成

您可以使用
zipWith (+) (integ f a m fa fm) (integ f m b fm fb)

代替
map (uncurry (+)) (zip (integ f a m fa fm) (integ f m b fm fb))

我认为更具可读性。

关于haskell - 将 "Why Functional Programming Matters"翻译成 Haskell,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1000145/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com