【问题标题】:Make a threadDelay-like function in Parsec - Haskell在 Parsec 中创建一个类似 threadDelay 的函数 - Haskell
【发布时间】:2019-02-06 17:52:06
【问题描述】:

在过去的几周里,我一直在按照 "Write Yourself a Scheme in 48 Hours" 指南在 Haskell 中使用 Parsec 制作自己的 Lisp-y 语言。请注意,我仍然是 Haskell 的初学者。

我正在尝试实现一个“睡眠”功能,该功能等待一段时间,然后在 REPL 输入命令后打印“true”,使用我来自 Parsec 的自定义类型(我没有使用词法分析器/令牌) .问题是当我在 REPL 中输入delay 函数时,它只是显示“完成”而不是挂起线程。另外,我使用的是“Control.Monad.Error”而不是“Control.Monad.Except”,因为本教程使用的是错误。

这是我的类型(为方便起见压缩):

-- All the custom data types, which follows the syntax: [Name - Haskell Type]
data Values = Atom String
         | Number Integer
         | InOut (IO ()) 
         | IOFunc ([Values] -> IOThrowsError Values) -- This is used for File and REPL IO

instance Show Values where show = showVal

这是我的“显示”功能(为了方便而压缩):

showVal :: Values -> String
showVal (InOut _) = "done"
showVal (IOFunc _) = "<primitive>"

最后是函数:

import Control.Concurrent (threadDelay)

dTime :: [Values] -> IOThrowsError Values
dTime [Number n] = 
    let delay' = fromIntegral n
    in (return . InOut) (threadDelay delay')

REPL 输出:

BuBBLE> (delay 1000) ; it works partially, but it immediately outputs `done`
done 

threadDelay 是否只在 GHC 中工作,或者我缺少什么才能让它工作?

完整来源:Ninjacop/BuBBLE

【问题讨论】:

  • 1000 的值是否原封不动地传递给 dTime?因为threadDelay 需要微秒,所以你只会暂停一毫秒。
  • 术语“延迟”和“dTime”未出现在您链接的“完整来源”中。请让问题自成一体,包括可运行的 MCVE。

标签: haskell functional-programming lisp parsec


【解决方案1】:

dTime 产生一个值,包含一个 IO 动作,如果你执行它,将暂停线程。好的。但是showVal 从不尝试执行任何IO——它只是看到,“这里有一个IO 操作”,但没有做任何事情。事实上,由于纯签名-&gt; String,它无法对其进行任何操作。为了让它也 eval,你可能想要使用 evalString :: Env -&gt; String -&gt; IO String 或其他东西。

【讨论】:

  • 我的代码中有完全相同的函数evalString,你是说我应该将它应用到dTime
  • 如果您希望延迟发生,您应该将其应用到(delay 1000)
猜你喜欢
  • 1970-01-01
  • 2021-11-11
  • 1970-01-01
  • 2011-11-18
  • 2017-09-07
  • 1970-01-01
  • 2018-03-22
  • 1970-01-01
  • 2017-07-24
相关资源
最近更新 更多