do-notation for building monoid values

Dear cafe, prompted by a discussion with the author of blaze-markup [1] I realized a pattern and would like to know whether other haskellers have exploited this/find this useful: For every monoid m, the types Writer m () and m are isomorphic as types via tell and execWriter. Moreover, Writer m is a monad if and only if m is a monoid. For every monad t, the type t () is a monoid with mempty = return () mappend = (>>). In the particular case of Writer m () and m, the isomorphism of Haskell types is in fact an isomorphism of monoids, that is, the functions tell and execWriter preserve the monoid operations. This enables us to use do-notation in building complicated values of any monoid type, e.g. Text or any other syntax. Instead of writing complicatedValue = component1 <> component2 <> modifier (component3 <> component4) one can write complicatedValue = execWriter $ do component1 component2 modifier $ do component3 component4 Should such an idiom be encouraged/discouraged? How do you handle the construction of monoid values (especially text-like) with interspersed function applications (e.g. show, prettyprint)? Regards, Olaf [1] https://github.com/jaspervdj/blaze-markup/issues/36

I always just use mconcat and lists, so instead of:
complicatedValue = execWriter $ do component1 component2 modifier $ do component3 component4
I write: complicatedValue = mconcat [ component1 , component2 , modifier . mconcat $ [component3, component4] ] Alternatively, if component3 and component4 are really long or lots of them linewrap those too: complicatedValue = mconcat [ component1 , component2 , modifier . mconcat $ [ component3 , component4 ] ] Cheers, Merijn
On 8 Mar 2018, at 14:02, Olaf Klinke
wrote: Dear cafe,
prompted by a discussion with the author of blaze-markup [1] I realized a pattern and would like to know whether other haskellers have exploited this/find this useful:
For every monoid m, the types Writer m () and m are isomorphic as types via tell and execWriter. Moreover, Writer m is a monad if and only if m is a monoid. For every monad t, the type t () is a monoid with mempty = return () mappend = (>>). In the particular case of Writer m () and m, the isomorphism of Haskell types is in fact an isomorphism of monoids, that is, the functions tell and execWriter preserve the monoid operations.
This enables us to use do-notation in building complicated values of any monoid type, e.g. Text or any other syntax. Instead of writing
complicatedValue = component1 <> component2 <> modifier (component3 <> component4)
one can write
complicatedValue = execWriter $ do component1 component2 modifier $ do component3 component4
Should such an idiom be encouraged/discouraged? How do you handle the construction of monoid values (especially text-like) with interspersed function applications (e.g. show, prettyprint)?
Regards, Olaf
[1] https://github.com/jaspervdj/blaze-markup/issues/36 _______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post.

I do the same thing that Merijn does. It works really well.
On Thu, Mar 8, 2018 at 8:08 AM, Merijn Verstraaten
I always just use mconcat and lists, so instead of:
complicatedValue = execWriter $ do component1 component2 modifier $ do component3 component4
I write:
complicatedValue = mconcat [ component1 , component2 , modifier . mconcat $ [component3, component4] ]
Alternatively, if component3 and component4 are really long or lots of them linewrap those too:
complicatedValue = mconcat [ component1 , component2 , modifier . mconcat $ [ component3 , component4 ] ]
Cheers, Merijn
On 8 Mar 2018, at 14:02, Olaf Klinke
wrote: Dear cafe,
prompted by a discussion with the author of blaze-markup [1] I realized a pattern and would like to know whether other haskellers have exploited this/find this useful:
For every monoid m, the types Writer m () and m are isomorphic as types via tell and execWriter. Moreover, Writer m is a monad if and only if m is a monoid. For every monad t, the type t () is a monoid with mempty = return () mappend = (>>). In the particular case of Writer m () and m, the isomorphism of Haskell types is in fact an isomorphism of monoids, that is, the functions tell and execWriter preserve the monoid operations.
This enables us to use do-notation in building complicated values of any monoid type, e.g. Text or any other syntax. Instead of writing
complicatedValue = component1 <> component2 <> modifier (component3 <> component4)
one can write
complicatedValue = execWriter $ do component1 component2 modifier $ do component3 component4
Should such an idiom be encouraged/discouraged? How do you handle the construction of monoid values (especially text-like) with interspersed function applications (e.g. show, prettyprint)?
Regards, Olaf
[1] https://github.com/jaspervdj/blaze-markup/issues/36 _______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post.
_______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post.
-- -Andrew Thaddeus Martin

The mconcat method is also how xmonad handles its ManageHooks, which are
basically Endo Monoids.
On Thu, Mar 8, 2018 at 8:48 AM, Andrew Martin
I do the same thing that Merijn does. It works really well.
On Thu, Mar 8, 2018 at 8:08 AM, Merijn Verstraaten
wrote:
I always just use mconcat and lists, so instead of:
complicatedValue = execWriter $ do component1 component2 modifier $ do component3 component4
I write:
complicatedValue = mconcat [ component1 , component2 , modifier . mconcat $ [component3, component4] ]
Alternatively, if component3 and component4 are really long or lots of them linewrap those too:
complicatedValue = mconcat [ component1 , component2 , modifier . mconcat $ [ component3 , component4 ] ]
Cheers, Merijn
On 8 Mar 2018, at 14:02, Olaf Klinke
wrote: Dear cafe,
prompted by a discussion with the author of blaze-markup [1] I realized a pattern and would like to know whether other haskellers have exploited this/find this useful:
For every monoid m, the types Writer m () and m are isomorphic as types via tell and execWriter. Moreover, Writer m is a monad if and only if m is a monoid. For every monad t, the type t () is a monoid with mempty = return () mappend = (>>). In the particular case of Writer m () and m, the isomorphism of Haskell types is in fact an isomorphism of monoids, that is, the functions tell and execWriter preserve the monoid operations.
This enables us to use do-notation in building complicated values of any monoid type, e.g. Text or any other syntax. Instead of writing
complicatedValue = component1 <> component2 <> modifier (component3 <> component4)
one can write
complicatedValue = execWriter $ do component1 component2 modifier $ do component3 component4
Should such an idiom be encouraged/discouraged? How do you handle the construction of monoid values (especially text-like) with interspersed function applications (e.g. show, prettyprint)?
Regards, Olaf
[1] https://github.com/jaspervdj/blaze-markup/issues/36 _______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post.
_______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post.
-- -Andrew Thaddeus Martin
_______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post.
-- brandon s allbery kf8nh sine nomine associates allbery.b@gmail.com ballbery@sinenomine.net unix, openafs, kerberos, infrastructure, xmonad http://sinenomine.net

Another mconcat user here. The only place it does fall down a bit is when
you want something to be optional. In a monad we have `when`, but I don't
know of any similar combinator for monoids. Of course, it's just `if x then
y else mempty`, but I always end up defining a when-like function over and
over again.
On Fri, Mar 9, 2018 at 12:53 AM Brandon Allbery
The mconcat method is also how xmonad handles its ManageHooks, which are basically Endo Monoids.
On Thu, Mar 8, 2018 at 8:48 AM, Andrew Martin
wrote: I do the same thing that Merijn does. It works really well.
On Thu, Mar 8, 2018 at 8:08 AM, Merijn Verstraaten < merijn@inconsistent.nl> wrote:
I always just use mconcat and lists, so instead of:
complicatedValue = execWriter $ do component1 component2 modifier $ do component3 component4
I write:
complicatedValue = mconcat [ component1 , component2 , modifier . mconcat $ [component3, component4] ]
Alternatively, if component3 and component4 are really long or lots of them linewrap those too:
complicatedValue = mconcat [ component1 , component2 , modifier . mconcat $ [ component3 , component4 ] ]
Cheers, Merijn
On 8 Mar 2018, at 14:02, Olaf Klinke
wrote: Dear cafe,
prompted by a discussion with the author of blaze-markup [1] I realized a pattern and would like to know whether other haskellers have exploited this/find this useful:
For every monoid m, the types Writer m () and m are isomorphic as types via tell and execWriter. Moreover, Writer m is a monad if and only if m is a monoid. For every monad t, the type t () is a monoid with mempty = return () mappend = (>>). In the particular case of Writer m () and m, the isomorphism of Haskell types is in fact an isomorphism of monoids, that is, the functions tell and execWriter preserve the monoid operations.
This enables us to use do-notation in building complicated values of any monoid type, e.g. Text or any other syntax. Instead of writing
complicatedValue = component1 <> component2 <> modifier (component3 <> component4)
one can write
complicatedValue = execWriter $ do component1 component2 modifier $ do component3 component4
Should such an idiom be encouraged/discouraged? How do you handle the construction of monoid values (especially text-like) with interspersed function applications (e.g. show, prettyprint)?
Regards, Olaf
[1] https://github.com/jaspervdj/blaze-markup/issues/36 _______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post.
_______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post.
-- -Andrew Thaddeus Martin
_______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post.
-- brandon s allbery kf8nh sine nomine associates allbery.b@gmail.com ballbery@sinenomine.net unix, openafs, kerberos, infrastructure, xmonad http://sinenomine.net _______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post.
participants (5)
-
Andrew Martin
-
Brandon Allbery
-
Merijn Verstraaten
-
Olaf Klinke
-
Oliver Charles