Chaining State Monad
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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
s序列,并使用上一步中的状态执行每个步骤?
例如,步骤如下
第一步产生(16,1)
然后我想用作n = 10
下一步的输入,它应该产生(6, 2)
。将第一步中的1添加到第一步中的16和使用新n中的第一步中的16。
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]
在每个step
列表上运行[25,10,5,1]
。调用
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))
希望有所帮助
以上是关于Chaining State Monad的主要内容,如果未能解决你的问题,请参考以下文章
Flutter 报错 DioError [DioErrorType.DEFAULT]: Bad state: Insecure HTTP is not allowed by platform(代码片段
重构typescript云函数使用promise chaining
Swift-可空链式调用(Optional Chaining)(十五)