Send Beginners mailing list submissions to beginners@haskell.org To subscribe or unsubscribe via the World Wide Web, visit http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners or, via email, send a message with subject or body 'help' to beginners-requ...@haskell.org
You can reach the person managing the list at beginners-ow...@haskell.org When replying, please edit your Subject line so it is more specific than "Re: Contents of Beginners digest..." Today's Topics: 1. Re: I can't turn-off conreate warning (Baa) 2. Re: I can't turn-off conreate warning (Sylvain Henry) 3. Count with Writer asynchronously (Baa) 4. Re: Count with Writer asynchronously (Michael Snoyman) 5. Re: Count with Writer asynchronously (Baa) ---------------------------------------------------------------------- Message: 1 Date: Mon, 24 Jul 2017 15:24:57 +0300 From: Baa <aqua...@gmail.com> To: beginners@haskell.org Subject: Re: [Haskell-beginners] I can't turn-off conreate warning Message-ID: <20170724152457.5fc6a30c@Pavel> Content-Type: text/plain; charset=US-ASCII Ohh, pardon :) My error: seems that `-fno-warn-orphans` works. Not -W but -f :-) > Hi, > > Maybe with -Wno-orphans > > https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/using-warnings.html?#ghc-flag--Worphans > > Regards, > Sylvain > > > On 24/07/2017 13:58, Baa wrote: > > Hello, Dear List! > > > > I want to turn-off concreate warning (but to have all other, and > > possible to treat them as errors). This warning is about orphans > > instances. I tried: > > > > -Wall -Werror -Wno-warn-orphans > > > > also > > > > -Wall -Werror -Wno-warn-warn-orphans > > > > But GHC does not understand this option. How to achieve this? > > > > > > -- > > Best regards, Paul > > _______________________________________________ > > Beginners mailing list > > Beginners@haskell.org > > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > > _______________________________________________ > Beginners mailing list > Beginners@haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners ------------------------------ Message: 2 Date: Mon, 24 Jul 2017 15:50:06 +0200 From: Sylvain Henry <sylv...@haskus.fr> To: beginners@haskell.org Subject: Re: [Haskell-beginners] I can't turn-off conreate warning Message-ID: <597c55b1-ffed-3d1f-21c4-1260eeb21...@haskus.fr> Content-Type: text/plain; charset=utf-8; format=flowed Quoting the manual: > To turn off any warning, simply give the corresponding -Wno-... option on the command line. For backwards compatibility with GHC versions prior to 8.0, all these warnings can still be controlled with -f(no-)warn-* instead of -W(no-)*. On 24/07/2017 14:24, Baa wrote: > Ohh, pardon :) > My error: seems that `-fno-warn-orphans` works. Not -W but -f :-) > > >> Hi, >> >> Maybe with -Wno-orphans >> >> https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/using-warnings.html?#ghc-flag--Worphans >> >> Regards, >> Sylvain >> >> >> On 24/07/2017 13:58, Baa wrote: >>> Hello, Dear List! >>> >>> I want to turn-off concreate warning (but to have all other, and >>> possible to treat them as errors). This warning is about orphans >>> instances. I tried: >>> >>> -Wall -Werror -Wno-warn-orphans >>> >>> also >>> >>> -Wall -Werror -Wno-warn-warn-orphans >>> >>> But GHC does not understand this option. How to achieve this? >>> >>> >>> -- >>> Best regards, Paul >>> _______________________________________________ >>> Beginners mailing list >>> Beginners@haskell.org >>> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners >> _______________________________________________ >> Beginners mailing list >> Beginners@haskell.org >> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > _______________________________________________ > Beginners mailing list > Beginners@haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners ------------------------------ Message: 3 Date: Tue, 25 Jul 2017 11:36:11 +0300 From: Baa <aqua...@gmail.com> To: The Haskell-Beginners Mailing List - Discussion of primarily beginner-level topics related to Haskell <beginners@haskell.org> Subject: [Haskell-beginners] Count with Writer asynchronously Message-ID: <20170725113611.12b050aa@Pavel> Content-Type: text/plain; charset=US-ASCII Hello, Dear List! There is package `async` (https://hackage.haskell.org/package/async-2.1.1.1/docs/Control-Concurrent-Async.html). Before, I had: import qualified Control.Concurent.Async as A ... runIt :: ... -> IO () ... sequence [A.async $ runIt ...] >>= mapM_ A.wait But now I want to count something inside `runIt`. I will use `Writer` monad for it (sure, it can be `State` also, not in principle to me). To do it synchronously, I done: module Main where import Control.Monad.Trans.Writer import Control.Monad.IO.Class import Data.Monoid runIt :: (Show a, Num a) => WriterT (Sum a) IO () -> a -> WriterT (Sum a) IO () runIt w x = do censor (+1) w -- emulates conditional count of something liftIO $ print x main = do let l = [1,2,3,4] w = writer ((), 0) :: WriterT (Sum Int) IO () z <- runWriterT $ sequence [runIt w i | i <- l] print $ snd z but now my `runIt` changes it's signature: runIt :: Num a => WriterT (Sum a) IO () -> ... -> WriterT (Sum a) IO () ... sequence [A.async $ runIt ...] >>= mapM_ A.wait ^^^^^^^^^^^ ` ERROR is here! I get the error because `async`::IO () -> IO (A.Async ()) but I'm trying to pass it `WriterT (Sum a) IO ()`! To fix it I added `runWriterT` there: res <- sequence [A.async $ runWriterT (runIt ...) ...] >>= mapM A.wait but now I will get list of counters, not one (res::[((), Sum Int)])! How to solve this problem: to run several actions asyncronously and to count something inside the action with `Writer` monad? === Best regards, Paul ------------------------------ Message: 4 Date: Tue, 25 Jul 2017 12:31:56 +0300 From: Michael Snoyman <mich...@snoyman.com> To: The Haskell-Beginners Mailing List - Discussion of primarily beginner-level topics related to Haskell <beginners@haskell.org> Subject: Re: [Haskell-beginners] Count with Writer asynchronously Message-ID: <CAKT9ecM+L8_eBtfP0=mpfkzunndfxd43mbnqj624oysw3k5...@mail.gmail.com> Content-Type: text/plain; charset="utf-8" Firstly, a direct answer to your question: use mconcat. main :: IO () main = do let l = [1,2,3,4] w = writer ((), 0) :: WriterT (Sum Int) IO () z <- sequence (map (A.async . runWriterT . runIt w) l) >>= mapM A.wait print $ snd $ mconcat z Under the surface, WriterT is using mappend to combine the `Sum` values anyway, so it's natural is `mconcat` (the version of mappend that applies to list) to get the same result. Now some possible improvements. You're not actually using the return value from the `runIt` call, just the writer value. There's a function called `execWriter` for this: z <- sequence (map (A.async . execWriterT . runIt w) l) >>= mapM A.wait print $ mconcat z Next, the combination of map and sequence can be written as traverse: z <- traverse (A.async . execWriterT . runIt w) l >>= mapM A.wait But the async library is cool enough that it provides a function called mapConcurrently that deals with the async/wait dance for you: main :: IO () main = do let l = [1,2,3,4] w = writer ((), 0) :: WriterT (Sum Int) IO () z <- A.mapConcurrently (execWriterT . runIt w) l print $ mconcat z One final note: usage of `print` like this in a concurrent context can run into interleaved output if you have the wrong buffer mode turned out, leading to output like this: 2 3 41 This is especially common when using runghc or ghci. You can either change the buffering mode or use a different output function like sayShow (from the say package, which I wrote): module Main where import qualified Control.Concurrent.Async as A import Control.Monad.Trans.Writer import Data.Monoid import Say runIt :: (Show a, Num a) => WriterT (Sum a) IO () -> a -> WriterT (Sum a) IO () runIt w x = do censor (+1) w -- emulates conditional count of something sayShow x main :: IO () main = do let l = [1,2,3,4] w = writer ((), 0) :: WriterT (Sum Int) IO () z <- A.mapConcurrently (execWriterT . runIt w) l sayShow $ mconcat z On Tue, Jul 25, 2017 at 11:36 AM, Baa <aqua...@gmail.com> wrote: > Hello, Dear List! > > There is package `async` > (https://hackage.haskell.org/package/async-2.1.1.1/docs/ > Control-Concurrent-Async.html). > > Before, I had: > > import qualified Control.Concurent.Async as A > ... > runIt :: ... -> IO () > ... > sequence [A.async $ runIt ...] >>= mapM_ A.wait > > But now I want to count something inside `runIt`. I will use > `Writer` monad for it (sure, it can be `State` also, not in > principle to me). To do it synchronously, I done: > > module Main where > > import Control.Monad.Trans.Writer > import Control.Monad.IO.Class > import Data.Monoid > > runIt :: (Show a, Num a) => WriterT (Sum a) IO () -> a -> WriterT (Sum > a) IO () > runIt w x = do > censor (+1) w -- emulates conditional count of something > liftIO $ print x > > main = do > let l = [1,2,3,4] > w = writer ((), 0) :: WriterT (Sum Int) IO () > z <- runWriterT $ sequence [runIt w i | i <- l] > print $ snd z > > but now my `runIt` changes it's signature: > > runIt :: Num a => WriterT (Sum a) IO () -> ... -> WriterT (Sum a) IO () > ... > sequence [A.async $ runIt ...] >>= mapM_ A.wait > ^^^^^^^^^^^ > ` ERROR is here! > > I get the error because `async`::IO () -> IO (A.Async ()) but I'm > trying to pass it `WriterT (Sum a) IO ()`! > > To fix it I added `runWriterT` there: > > res <- sequence [A.async $ runWriterT (runIt ...) ...] >>= mapM A.wait > > but now I will get list of counters, not one (res::[((), Sum Int)])! > > How to solve this problem: to run several actions asyncronously and to > count something > inside the action with `Writer` monad? > > > === > Best regards, Paul > _______________________________________________ > Beginners mailing list > Beginners@haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.haskell.org/pipermail/beginners/attachments/20170725/5aae9422/attachment-0001.html> ------------------------------ Message: 5 Date: Tue, 25 Jul 2017 13:29:04 +0300 From: Baa <aqua...@gmail.com> To: beginners@haskell.org Subject: Re: [Haskell-beginners] Count with Writer asynchronously Message-ID: <20170725132904.43b84b3e@Pavel> Content-Type: text/plain; charset=US-ASCII Hello, Michael! This answers to my question completely, thank you so much! But looking at this code, I thought: how is it right to wrap/unwrap write monad? In languages like C or Python we can pass input/output argument (`int*` in C or `[0]` in Python) and use it as some accumulator. But here writer monad is not using as accumulator, accumulating (summation) happens in `mconcat`, right? It's using only as output value, i.e. place to "yield" result. I mean `w` is 0, each call of `runIt` sets there 1, after all calls we calculate sum of this 1's. And instead of `censor (+1) w` I can do `tell 1` only. It means that `runIt` can return not `IO ()` but `IO Int` and results of all `runIt`'s asynchnronously gotten values can be accumulated with `mconcat` without using of writer monad. Am I right, writer monad here is not accumulator but only output value (like output arguments in C/C++/IDL/etc)? How is this a typical solution in Haskell - to use writer monad with wrap/unwrap multiple times, only to save output value? On Tue, 25 Jul 2017 12:31:56 +0300 Michael Snoyman <mich...@snoyman.com> wrote: > Firstly, a direct answer to your question: use mconcat. > > main :: IO () > main = do > let l = [1,2,3,4] > w = writer ((), 0) :: WriterT (Sum Int) IO () > z <- sequence > (map (A.async . runWriterT . runIt w) l) > >>= mapM A.wait > print $ snd $ mconcat z > > Under the surface, WriterT is using mappend to combine the `Sum` > values anyway, so it's natural is `mconcat` (the version of mappend > that applies to list) to get the same result. Now some possible > improvements. > > You're not actually using the return value from the `runIt` call, > just the writer value. There's a function called `execWriter` for > this: > > z <- sequence > (map (A.async . execWriterT . runIt w) l) > >>= mapM A.wait > print $ mconcat z > > Next, the combination of map and sequence can be written as traverse: > > z <- traverse (A.async . execWriterT . runIt w) l > >>= mapM A.wait > > But the async library is cool enough that it provides a function > called mapConcurrently that deals with the async/wait dance for you: > > main :: IO () > main = do > let l = [1,2,3,4] > w = writer ((), 0) :: WriterT (Sum Int) IO () > z <- A.mapConcurrently (execWriterT . runIt w) l > print $ mconcat z > > One final note: usage of `print` like this in a concurrent context > can run into interleaved output if you have the wrong buffer mode > turned out, leading to output like this: > > 2 > 3 > 41 > > This is especially common when using runghc or ghci. You can either > change the buffering mode or use a different output function like > sayShow (from the say package, which I wrote): > > module Main where > > import qualified Control.Concurrent.Async as A > import Control.Monad.Trans.Writer > import Data.Monoid > import Say > > runIt :: (Show a, Num a) > => WriterT (Sum a) IO () > -> a > -> WriterT (Sum a) IO () > runIt w x = do > censor (+1) w -- emulates conditional count of something > sayShow x > > main :: IO () > main = do > let l = [1,2,3,4] > w = writer ((), 0) :: WriterT (Sum Int) IO () > z <- A.mapConcurrently (execWriterT . runIt w) l > sayShow $ mconcat z > > > On Tue, Jul 25, 2017 at 11:36 AM, Baa <aqua...@gmail.com> wrote: > > > Hello, Dear List! > > > > There is package `async` > > (https://hackage.haskell.org/package/async-2.1.1.1/docs/ > > Control-Concurrent-Async.html). > > > > Before, I had: > > > > import qualified Control.Concurent.Async as A > > ... > > runIt :: ... -> IO () > > ... > > sequence [A.async $ runIt ...] >>= mapM_ A.wait > > > > But now I want to count something inside `runIt`. I will use > > `Writer` monad for it (sure, it can be `State` also, not in > > principle to me). To do it synchronously, I done: > > > > module Main where > > > > import Control.Monad.Trans.Writer > > import Control.Monad.IO.Class > > import Data.Monoid > > > > runIt :: (Show a, Num a) => WriterT (Sum a) IO () -> a -> > > WriterT (Sum a) IO () > > runIt w x = do > > censor (+1) w -- emulates conditional count of something > > liftIO $ print x > > > > main = do > > let l = [1,2,3,4] > > w = writer ((), 0) :: WriterT (Sum Int) IO () > > z <- runWriterT $ sequence [runIt w i | i <- l] > > print $ snd z > > > > but now my `runIt` changes it's signature: > > > > runIt :: Num a => WriterT (Sum a) IO () -> ... -> WriterT (Sum > > a) IO () ... > > sequence [A.async $ runIt ...] >>= mapM_ A.wait > > ^^^^^^^^^^^ > > ` ERROR is here! > > > > I get the error because `async`::IO () -> IO (A.Async ()) but I'm > > trying to pass it `WriterT (Sum a) IO ()`! > > > > To fix it I added `runWriterT` there: > > > > res <- sequence [A.async $ runWriterT (runIt ...) ...] >>= mapM > > A.wait > > > > but now I will get list of counters, not one (res::[((), Sum Int)])! > > > > How to solve this problem: to run several actions asyncronously and > > to count something > > inside the action with `Writer` monad? > > > > > > === > > Best regards, Paul > > _______________________________________________ > > Beginners mailing list > > Beginners@haskell.org > > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > > ------------------------------ Subject: Digest Footer _______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners ------------------------------ End of Beginners Digest, Vol 109, Issue 18 ******************************************