haskell - 如何检查之前是否调用过函数?

标签 haskell

我有一个函数需要一些时间来处理一些输入。

我想做的是,如果用户调用该函数,它会开始做它所做的事情,但如果用户再次调用它,并且它仍在处理这件事,它会返回一条消息,告诉用户坐下紧。

runService :: Arg1 -> Arg2 -> IO String
runService arg1 arg2 = do

     isRunning <- {- Check if the function is running -}
     isDone    <- {- Check if the function is done working -}

     if isRunning
        then return "Work is in progress!"
        else if isDone 
                then return "Work is done."
                else do startService arg1 arg2
                        return "Work has been started."

我相信我还需要修改 startService 函数,但我不确定如何修改。

这是它当前的类型签名。

startService :: Arg1 -> Arg2 -> IO ()

如果 runService 可以提供某种“进度条”,那将会更有用

runService :: Arg1 -> Arg2 -> IO String
runService arg1 arg2 = do

     isRunning <- {- Check if the function is running -}
     isDone    <- {- Check if the function is done working -}

     if isRunning
        then {- Return some progress indicator -}
        else if isDone 
                then return "Work is done."
                else do startService arg1 arg2
                        return "Work has been started."
                        {- Return some progress indicator -}

startService 使用 putStrLn 打印其状态相当简单,但我不确定如何将这些状态字符串提供给 runService 或我如何将此状态一直向上连接到 main

对于过程语言,这将需要一个全局变量。在 Haskell 中寻找类似的东西让我找到了 StateT、ReaderT、WriterT monad 转换器,但我很难理解它们以及它们在一般情况下和在这个特定上下文中的用法。

最佳答案

您提出的设计方法类型看起来深受命令式编程背景的影响。对此要小心,因为尽管您可以在 Haskell 中进行命令式编程,并模仿一些常见的命令式模式和行为,但这样做会充满挫折感,并没有真正的好处。

所以您想从功能上看一下:

  • 您想从另一个计算中观察一个计算的状态,这意味着您将需要多个线程来实现并发
  • 你想在线程之间传递消息,所以你需要一些原语来传递消息。 Many options exists for that .

基本上,您可以做的是在计算线程和观察线程之间共享并发原语(想想可变框引用)。这足以实现常见的行为,例如同步(锁定观察线程直到计算完成并传递结果)或等待(计算完成了吗?是/否)。

观察进度是另一个涉及计算功能合作的问题。如果您可以按步骤划分工作,您可能应该使用连续传递样式,这样您就可以保持函数的纯净。此函数将执行一个计算步骤,然后返回一对(估计进度比率,下一步)。

IO 中的另一个函数将继续调用计算函数并使用进度率更新共享状态,直到工作完成。

在共享框内,使用代数数据类型:

data ComputationState result = Working Float -- progress ratio
                             | Done result   -- done, get the result

给你。

关于haskell - 如何检查之前是否调用过函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62221286/

相关文章:

haskell - 商店comonad 是什么?

haskell - 在 Haskell 中构建一棵树

haskell - 允许查看最终结果的一部分的变质

haskell - Haskell 中递归元组函数的困难

Haskell 可扩展 IO 异常?

haskell - 为什么我们需要 Maybe Monad 而不是 Monad

haskell - 在 Haskell 中读取和处理多个文件

haskell - 如何防止 scotty 为大文本输出占用内存?

haskell - 一个构造函数产生一元计算的AST的表达式准引用器?

haskell - 在 ghci 中设置选项