在过去的几周里,遵循"Write Yourself a Scheme in 48 Hours"指南,我一直在Haskell中使用Parsec来编写自己的Lisp-y语言。请注意,我仍然是Haskell的初学者。
我正在尝试使用“ Parsec”中的自定义类型在REPL输入命令后实现等待一定时间的“睡眠”功能,然后输出“ true”(我未使用词法分析器/令牌) 。问题是,当我在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
答案 0 :(得分:3)
---
reminders:
reminder_a:
-
reminder_b:
-
产生的值包含 一个dTime
动作,如果您执行了该动作,它将暂停线程。好。但是IO
从未尝试执行任何showVal
–它只是看到“这里有一个IO
动作”,但是对此却无能为力。实际上,由于纯签名IO
,它无法执行任何操作。要使其等效,您可能需要使用-> String
或其他名称。