I want to receive a string, convert it to a list and write every element of the list into a TChan. For every string received I want to fork a new process.
My problem is that I get errors related to IO when I try to compile this:
Couldn't match expected type `IO ()' with actual type `[()]'
or
Couldn't match expected type `IO ()' with actual type `[IO ()]'
Whilst I completely understand the error and know where it originates from ( – at least the first error – ) I am now out of ideas how I could split IO an computation in my example and still achieve what I try to do.
write2TChan msg mtch = do
let mymessages = words msg
map (\x -> atomically $ writeTChan mtch x) mymessages
return ()
main = withSocketsDo $ do
s <- socket AF_INET Datagram defaultProtocol
bindAddr <- inet_addr host
bindSocket s (SockAddrInet port bindAddr)
mtch <- newTChanIO
let forever socket hosts = do
(msg, host) <- receiveMessage socket
return ()
return (forkIO $ write2TChan msg mtch)
--forkIO $ write2TChan msg mtch
--tried w return () and above, same problem
forever socket hosts
forever s []
sClose s
maphas the typemap :: (a -> b) -> [a] -> [b], so it always returns a list. However, every statement in adoblock in theIOmonad must have typeIO afor somea.You want the related function
mapM :: Monad m => (a -> m b) -> [a] -> m [b]which does the same thing in a monad. Since you want to ignore the result, we can use the variantmapM_ :: Monad m => (a -> m b) -> [a] -> m ().For your other function you should be able to use
forkIOdirectly. Wrapping it inreturnmakes no sense at all, as that would make the typeIO (IO a), i.e. an action returning an action. Also,return ()is a no-op when it’s not the last statement in adoblock, so you don’t need that.This should work
though, the
hostsargument is currently always[], so unless you plan to do something about that, you can get rid of that, too. Also, I would avoid the nameforeversince there is already a commonly used function inControl.Monadwith that name.