作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个应用程序需要处理队列上的一些项目。有时脱下元素,有时穿上新元素。鉴于 haskell 数据结构的不变性,我对如何实现这一点感到困惑。这是我的实验代码
module Main where
import Data.Dequeue as D
import Data.Time
import Control.Concurrent (threadDelay)
import Control.Monad (forever)
data ScheduledCall = ScheduledCall {
not_before :: UTCTime
, apiParameters :: String
}
sleep :: Int -> IO ()
sleep n = threadDelay (n * 1000 * 1000)
main :: IO ()
main = do
let workQ :: D.BankersDequeue ScheduledCall
workQ = D.empty
now <- getCurrentTime
forever $ do
let workQ' = D.pushBack workQ (ScheduledCall now "first")
-- possibly do something with the items
let len = length workQ'
let workQ = workQ'
putStrLn $ "Length " ++ (show len)
sleep 5
使用这段代码,我希望看到出队在每次迭代中增加 1,但事实并非如此。这意味着结构保持不变。
如何通过不同的迭代使用出队?
最佳答案
您可以使用递归。
main = do
now <- getCurrentTime
let loop workQ = do
let workQ' = D.pushBack workQ (ScheduledCall now "first")
-- possibly do something with the items
let len = length workQ'
putStrLn $ "Length " ++ (show len)
sleep 5
loop workQ' -- recurse with the new queue
loop D.empty -- start the loop with an initially empty dqueue
有更先进(和复杂)的技术来建模可变性,例如使用 IORef 或 ST/State monad,但是对于简单的情况,基本的递归定义就足够了。
请注意,您不能像尝试那样“重新分配”:
let workQ = workQ'
putStrLn $ "Length " ++ (show len)
sleep 5
这定义了一个新变量workQ
,它与上面定义的同名的其他变量完全无关。新变量的作用域只有下面几行,没有使用它,所以它是一个无用的定义。
您可以将这种重新定义视为 C++ 中发生的重新定义:
{
Dqueue workQ = ... ;
stuff();
if (blah) {
Dqueue workQ = ... ;
// this does not affect the outer variable
}
}
定义一个与外部作用域中定义的另一个变量同名的变量称为“遮蔽”。 GHC 会对此发出警告(如果您启用警告),因为这通常是一个错误。
关于haskell - haskell出队的不变性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74959485/
我是一名优秀的程序员,十分优秀!