繁体   English   中英

使用状态monad的euler项目14

[英]project euler 14 using the state monad

我正在通过欧拉计画(再次)自学Haskell。 问题14( https://projecteuler.net/problem=14 )恳求动态编程,而且从历史上看,我一直是反单子(由于反复地未能学会足够好地使用它们以使生活更轻松而不是更艰难) ),所以我想咬一下子弹,并使用State monad来记住我的代码……进展不顺利。 我想说的很清楚,我已经以简单/缓慢的方式解决了这个问题,在这一点上,我正在尝试学习一些东西(即Euler 14号Haskell项目不是我想要的)。

到目前为止,我的代码是:

collatzMemoCheck :: Int -> State (Map Int Int) Int
collatzMemoCheck n = state $ \s -> maybe (let (a, s') = runState (collatzFast n) s
                                          in (a+1, Map.insert n (a+1) s'))
                                         (\len -> (len, s))
                                         (Map.lookup n s)

collatzFast :: Int -> State (Map Int Int) Int
collatzFast 1 = state $ \_ -> (1, Map.singleton 1 1)
collatzFast n
  | even n    = collatzMemoCheck (n `quot` 2)
  | otherwise = collatzMemoCheck (3 * n + 1)

它适用于cabal repl中的单个查询,但是对于我一生来说,我不知道如何确定对collat​​zFast的重复调用的状态。 我想要类似的东西

-- DOES NOT WORK
allCollatzLengths = scanl (>>= collatzFast) (return Map.empty) [1..999999]

但我认为这是由内而外的。 绑定发生之前的状态计算的结果部分,并将其传递到下一个电话,但我想它拿以前的状态计算的静态部分,并把它传递给下一个电话。

有没有正确的方法来做到这一点,或者我已将自己画在一个角落里? 如果我不能使用>> =,那么拥有monad有什么意义? ...还是没有意义,因为这是一种愚蠢的做法? 救命?

你可能会喜欢

mapM :: Monad m => (a -> m b) -> [a] -> m [b]

特别是mapM collatzFast :: [Int] -> State (Map Int Int) [Int]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM