

Again on breaking loops at Haskell
source link: https://www.codesd.com/item/again-on-breaking-loops-at-haskell.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Again on breaking loops at Haskell
I have a small piece of code that receives frames on a zeromq Pull socket and displays it in a opencv window:
module Main where
import Control.Monad
import qualified OpenCV as CV
import System.ZMQ4.Monadic
import System.Exit
main :: IO()
main = runZMQ $ do
receiver <- socket Pull
bind receiver "tcp://*:5554"
-- do some stuff not relevant
forever $ do
buffer <- receive receiver
let img = CV.imdecode CV.ImreadUnchanged buffer -- simple decoder
liftIO $ CV.withWindow "Video" $ \window -> do
CV.imshow window img
key <- CV.waitKey 10
when (key == 27) exitSuccess -- <- UGLY!
What I would like to find is a way to break the loop that allows me more control. I'm aware of the EitherT solution proposed by Gabriel Gonzalez here (that I like very much) but I'm not able to implement it in the CV.withWindow
context, for example:
quit :: (Monad m) => e -> EitherT e m r
quit = left
loop :: (Monad m) => EitherT e m a -> m e
loop = fmap (either id id) . runEitherT . forever
main :: IO()
main = runZMQ $ do
receiver <- socket Pull
bind receiver "tcp://*:5554"
loop $ do
buffer <- receive receiver
let img = CV.imdecode CV.ImreadUnchanged buffer -- simple decoder
liftIO $ CV.withWindow "Video" $ \window -> do
CV.imshow window img
key <- CV.waitKey 10
when (key == 27) $ quit ()
But of course quit
wraps the argument in a Left and this solution doesn't compile.
Read and write an IORef
, and use whileM_
.
main = runZMQ $ do
receiver <- socket Pull
bind receiver "tcp://*:5554"
continue <- liftIO $ newIORef True
whileM_ (liftIO $ readIORef continue) $ do
buffer <- receive receiver
let img = CV.imdecode CV.ImreadUnchanged buffer -- simple decoder
liftIO . CV.withWindow "Video" $ \window -> do
CV.imshow window img
key <- CV.waitKey 10
when (key == 27) $ writeIORef continue False
Or have your loop call itself explicitly as appropriate:
main = runZMQ $ do
receiver <- socket Pull
bind receiver "tcp://*:5554"
let loop = do
buffer <- receive receiver
let img = CV.imdecode CV.ImreadUnchanged buffer -- simple decoder
key <- liftIO . CV.withWindow "Video" $ \window -> do
CV.imshow window img
CV.waitKey 10
when (key /= 27) loop
loop
Recommend
-
145
31 October 2017JavaScript loops - how to handle async/await
-
81
Kotlin does not have C-style for-loops. This is fine because I prefer using the idiomatic for-loops (built to use iterators) anyway. But there is a big problem: Kotlin does not allow dynamic limiting conditions in its for-loops (See this thread)...
-
24
How do we get better faster? It’s amazing to consider the amount of money, thought and effort that has gone into solving that one simple problem in software development over the past 2 decades. Here’s a sma...
-
34
A foreach loop runs a block of code for each element of a list. No big whoop,...
-
39
Today, we're going to discuss control structures and loops in PHP. I'll show you how to use all the main control structures that are supported in PHP, like if, else, for, foreach, while and more. What Is a Contr...
-
31
On slack the other day, someone mentioned that lots of companies don't use range-based for loops in their code because they use PascalCase identifiers, and their containers thus have
-
4
This document describes a list of upcoming/proposed changes to Haskell core/de facto libraries. Ongoing: the change is already rolled out. Upcoming: the change is made upstream, and will...
-
7
The Breaking Point Is Here—AgainTragedies converge, apocalypse colors the air, and digital realities no longer suffice. Eventually everything, and everyone, cracks.
-
6
[repost] man's breaking the rules again, I can't even imagine [repost] man's breaking the rules again, I can't even imagine
-
4
Breaking things again Yeah, I do that quite a bit. The site was down for a bit on and off the last couple of days because of a fatal error. It was the Gutenberg plugin having some hiccups. It was fine since it wa...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK