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的不同值运行ns序列,并使用上一步中的状态执行每个步骤?

例如,步骤如下

第一步产生(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的主要内容,如果未能解决你的问题,请参考以下文章

`State#` 的规范

Flutter 报错 DioError [DioErrorType.DEFAULT]: Bad state: Insecure HTTP is not allowed by platform(代码片段

重构typescript云函数使用promise chaining

Swift-可空链式调用(Optional Chaining)(十五)

Swift-可空链式调用(Optional Chaining)(十五)

Haskell Monad(下)