更新Haskell中的值?
我试图写一个函数,它不断地接受整数值并输出到目前为止给定的最大值 这似乎和一个简单的问题一样简单更新Haskell中的值?,haskell,Haskell,我试图写一个函数,它不断地接受整数值并输出到目前为止给定的最大值 这似乎和一个简单的问题一样简单 max a b = maximum [a,b] 但是函数应该“记住”过去给它的值,并将新值与那些值进行比较 例如:我想以-500开头的初始值。如果我用参数5调用函数,那么它应该返回5,因为5大于-500 如果我再次调用该函数,这次的参数是3,它仍然应该返回5,因为即使3大于-500,它也小于5 这在无副作用的编程中可能吗?这是alpha-beta的直接翻译,我还没有测试过,但我希望它能得到翻译算法
max a b = maximum [a,b]
但是函数应该“记住”过去给它的值,并将新值与那些值进行比较
例如:我想以-500
开头的初始值。如果我用参数5
调用函数,那么它应该返回5
,因为5大于-500
如果我再次调用该函数,这次的参数是3
,它仍然应该返回5
,因为即使3
大于-500
,它也小于5
这在无副作用的编程中可能吗?这是alpha-beta的直接翻译,我还没有测试过,但我希望它能得到翻译算法的一般方法,即使它不是完全正确的
alphaBeta ::
(state -> Int) -- heuristic
-> (state -> Bool -> [state]) -- next states
-> state
-> Int -- depth
-> Int -- alpha
-> Int -- beta
-> Bool -- is max player
-> Int -- score
alphaBeta heu children = go where
go s d a b p | d == 0 || null ss = heu s
| otherwise = score
where
ss = children s p
score = fst $ head $ case p of
True ->
takeWhile ((<b) . snd) $ scanl step (minBound, a) ss where
step (v, a) s = (v', max a v') where
v' = max v (go s (d - 1) a b (not p))
False ->
takeWhile ((a<) . snd) $ scanl step (maxBound, b) ss where
step (v, b) s = (v', min b v') where
v' = min v (go s (d - 1) a b (not p))
在无副作用编程中是否可能有副作用…不,可能会有帮助。但是有没有一种方法可以做到这一点,而不使其成为副作用对于初学者来说,合理的答案只能是:没有-而是让你记住的东西现在成为你函数的参数(状态单子只是使其隐式)-顺便问一句,当你可以使用(在你的例子中)时,为什么你想要这样的东西只需
maximum
列出所有要查找max.元素的内容就可以了?我正在尝试alpha-beta修剪,因此我需要一个不断限制alpha和beta界限的函数。从(-500500)开始,这真的没有问题-只需传递您的alpha/beta值(并返回更新版本)-它甚至会让您更好地理解算法当然,在这种情况下,它可能会变得乏味,状态单子可能毕竟不是一个坏主意-但我建议你只在你已经理解了这些东西的情况下使用它-如果你现在不坚持使用显式的参数/返回-看起来很有趣,我只是想理解scanl,它似乎需要一个困境、一个值和一个列表,但是在你的代码中,它是一个元组和一个列表?类似于foldl
,但收集部分结果。
import Control.Monad
alphaBeta ::
(state -> Int) -- heuristic
-> (state -> Bool -> [state]) -- next states
-> state
-> Int -- depth
-> Int -- alpha
-> Int -- beta
-> Bool -- is max player
-> Int -- score
alphaBeta heu children = go where
go s d a b p | d == 0 || null ss = heu s
| otherwise = score
where
ss = children s p
score = either id fst $ case p of
True ->
foldM step (minBound, a) ss where
step (v, a) s | b <= a' = Left v'
| otherwise = Right (v', a')
where v' = max v (go s (d - 1) a b (not p))
a' = max a v'
False ->
foldM step (maxBound, b) ss where
step (v, b) s | b' <= a = Left v'
| otherwise = Right (v', b')
where v' = min v (go s (d - 1) a b (not p))
b' = min b v'