链接状态 Monad
Chaining State Monad
我有一个功能
step :: Int -> State Int Int
step n = get >>= \x -> put (x `div` n) >> return (x `mod` n)
λ> runState (step 25) 41
(16,1)
我如何 运行 一个 step
的序列,具有不同的 n
值,并且每个步骤都使用上一步的状态?
例如,步骤如下
第一步产生 (16,1)
,然后我想将其用作下一步 n = 10
的输入,它应该产生 (6, 2)
。添加第一步中的 1,第一步中的 16 为 mod,新的 n.
n = 25 gives (16,1) then
n = 10 gives (6,2) then
n = 5 gives (1,3) then
n = 1 gives (0,4)
我知道在这里使用 State
可能不正确;但我正在尝试将其作为一种学习方式。
可能的目标是用状态 monad 来实现这个功能。
greedy :: Double -> Int
greedy owed = snd $ foldl go (pennies,0) [25, 10, 5, 1]
where
pennies = floor . (*100) $ owed
go (remaining,counter) coin = (remaining',counter')
where
remaining' = remaining `mod` coin
counter' = counter + remaining `div` coin
函数,
mapM step [25,10,5,1]
或更一般的
traverse step [25,10,5,1]
对 [25,10,5,1]
的每个列表运行 step
。调用
runState (mapM step [25,10,5,1]) 41
运行初始状态设置为41
的函数,返回步骤输出列表和最终状态。
([16,1,0,0],0)
如果您想将状态与输出一起列出,只需修改 step
以包含它们。
step n = get >>= \x -> put (x `div` n) >> return ((x `mod` n),(x `div` n))
或者,换句话说
step n = do
x <- get
let (r,x') = (x `mod` n,x `div` n)
put x'
return (r,x')
结果是,([(16,1),(1,0),(0,0),(0,0)],0)
,仍然不是你要找的,但更接近了。恐怕我不太了解你的方程式的细节,无法得到你要找的东西,但这应该有助于理清状态部分,让你专注于数学。
要实现上述 go
功能:
go n = do
(r,c) <- get
let (r',c') = (r `mod` n, c + (r `div` n))
put (r',c')
return (r',c')
和
runState (mapM go [25,10,5,1]) (41,0)
产量,
([(16,1),(6,2),(1,3),(0,4)],(0,4))
希望对您有所帮助
我有一个功能
step :: Int -> State Int Int
step n = get >>= \x -> put (x `div` n) >> return (x `mod` n)
λ> runState (step 25) 41
(16,1)
我如何 运行 一个 step
的序列,具有不同的 n
值,并且每个步骤都使用上一步的状态?
例如,步骤如下
第一步产生 (16,1)
,然后我想将其用作下一步 n = 10
的输入,它应该产生 (6, 2)
。添加第一步中的 1,第一步中的 16 为 mod,新的 n.
n = 25 gives (16,1) then
n = 10 gives (6,2) then
n = 5 gives (1,3) then
n = 1 gives (0,4)
我知道在这里使用 State
可能不正确;但我正在尝试将其作为一种学习方式。
可能的目标是用状态 monad 来实现这个功能。
greedy :: Double -> Int
greedy owed = snd $ foldl go (pennies,0) [25, 10, 5, 1]
where
pennies = floor . (*100) $ owed
go (remaining,counter) coin = (remaining',counter')
where
remaining' = remaining `mod` coin
counter' = counter + remaining `div` coin
函数,
mapM step [25,10,5,1]
或更一般的
traverse step [25,10,5,1]
对 [25,10,5,1]
的每个列表运行 step
。调用
runState (mapM step [25,10,5,1]) 41
运行初始状态设置为41
的函数,返回步骤输出列表和最终状态。
([16,1,0,0],0)
如果您想将状态与输出一起列出,只需修改 step
以包含它们。
step n = get >>= \x -> put (x `div` n) >> return ((x `mod` n),(x `div` n))
或者,换句话说
step n = do
x <- get
let (r,x') = (x `mod` n,x `div` n)
put x'
return (r,x')
结果是,([(16,1),(1,0),(0,0),(0,0)],0)
,仍然不是你要找的,但更接近了。恐怕我不太了解你的方程式的细节,无法得到你要找的东西,但这应该有助于理清状态部分,让你专注于数学。
要实现上述 go
功能:
go n = do
(r,c) <- get
let (r',c') = (r `mod` n, c + (r `div` n))
put (r',c')
return (r',c')
和
runState (mapM go [25,10,5,1]) (41,0)
产量,
([(16,1),(6,2),(1,3),(0,4)],(0,4))
希望对您有所帮助