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
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.
Is the value
1000
is getting passed unchanged todTime
? BecausethreadDelay
takes microseconds so you would only be pausing for a millisecond.– David Fletcher
Aug 31 at 17:23