gpt4 book ai didi

haskell - haskell出队的不变性

转载 作者:行者123 更新时间:2023-12-02 01:24:54 27 4
gpt4 key购买 nike

我有一个应用程序需要处理队列上的一些项目。有时脱下元素,有时穿上新元素。鉴于 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/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com