在Parsec-Haskell

时间:2018-08-31 16:54:59

标签: haskell functional-programming lisp parsec

在过去的几周里,遵循"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

1 个答案:

答案 0 :(得分:3)

--- reminders: reminder_a: - reminder_b: - 产生的值包含 一个dTime动作,如果您执行了该动作,它将暂停线程。好。但是IO从未尝试执行任何showVal –它只是看到“这里有一个IO动作”,但是对此却无能为力。实际上,由于纯签名IO,它无法执行任何操作。要使其等效,您可能需要使用-> String或其他名称。