I have the following program, which produces no output when run with runhaskell Toy.hs
, and instead hangs indefinitely. By my understanding, the program should print "hi" and then exit. I would appreciate an answer and/or advice about how to debug such an issue. I'm using Pipes 4.0.0 off of github (github.com/Gabriel439/Haskell-Pipes-Library).
module Toy where
import Pipes
import Control.Monad.State
type Request = String
type Response = String
serveChoice :: Request -> Server Request Response IO ()
serveChoice = forever go
where go req = do
lift $ putStrLn req
respond req
run :: Monad m => () -> Client Request Response (StateT Int m) ()
run () = do
request "hi"
return ()
main :: IO ()
main = evalStateT (runEffect $ hoist lift . serveChoice >-> run $ ()) 0
Pipe is used to combine two or more commands, and in this, the output of one command acts as input to another command, and this command's output may act as input to the next command and so on. It can also be visualized as a temporary connection between two or more commands/ programs/ processes.
pipe() is a system call that facilitates inter-process communication. It opens a pipe, which is an area of main memory that is treated as a "virtual file". The pipe can be used by the creating process, as well as all its child processes, for reading and writing.
A pipe is a system call that creates a unidirectional communication link between two file descriptors. The pipe system call is called with a pointer to an array of two integers. Upon return, the first element of the array contains the file descriptor that corresponds to the output of the pipe (stuff to be read).
pipe() is a Linux system function. The pipe() system function is used to open file descriptors, which are used to communicate between different Linux processes. In short, the pipe() function is used for inter-process communication in Linux.
You need to use foreverK
instead of forever
, like this:
module Toy where
import Pipes
import Pipes.Prelude (foreverK)
import Control.Monad.State
type Request = String
type Response = String
serveChoice :: Request -> Server Request Response IO ()
serveChoice = foreverK go
where go req = do
lift $ putStrLn req
respond req
run :: Monad m => () -> Client Request Response (StateT Int m) ()
run () = do
request "hi"
return ()
main :: IO ()
main = evalStateT (runEffect $ hoist lift . serveChoice >-> run $ ()) 0
The reason your original version hangs is that you used forever
in the Reader
monad (i.e. the ((->) a)
monad) and not the pipe monad. Within this monad, forever
is equivalent to ⊥
:
-- i.e. m b -> m c
forever :: (a -> b) -> (a -> c)
forever m = m >> forever m
= m >>= \_ -> forever m
= \a -> (\_ -> forever m) (m a) a
= \a -> forever m a
= forever m
foreverK
is probably what you wanted, since it is the same idiom for Server
s introduced in the pipes-3.3.0
tutorial.
This change fixes the program which now completes normally:
>>> main
hi
>>>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With