instance Monoid a => Monad ((,) a)

I wanted to define a simple Monad instance for (Bool,) as instance Monad ((,) Bool) where return x = (False, x) (True, x) >>= k = (True, snd (k x)) (False, x) >>= k = k x -- or: (b, x) >>= k = let (c, y) = k x in (b||c, y) The idea was to keep track of whether functions change their input value or not. To my astonishment I found that this definition overlaps with an existing one. GHC tells me x.hs:2:10: error: • No instance for (Monoid Bool) arising from the superclasses of an instance declaration • In the instance declaration for ‘Monad ((,) Bool)’ | 2 | instance Monad ((,) Bool) where | ^^^^^^^^^^^^^^^^ x.hs:2:10: error: • Overlapping instances for Monad ((,) Bool) arising from a use of ‘GHC.Base.$dm>>’ Matching instances: instance Monoid a => Monad ((,) a) -- Defined in ‘GHC.Base’ instance Monad ((,) Bool) -- Defined at x.hs:2:10 • In the expression: GHC.Base.$dm>> @((,) Bool) In an equation for ‘>>’: (>>) = GHC.Base.$dm>> @((,) Bool) In the instance declaration for ‘Monad ((,) Bool)’ | 2 | instance Monad ((,) Bool) where | ^^^^^^^^^^^^^^^^ [one more similar overlap error elided] But I could not find the instance Monoid a => Monad ((,) a) documented anywhere in the base package. Should I look harder? Or is this instance accidentally leaking from GHC.Base? Eventually, through some experimenting I found that if I replace Bool with Any, then the existing instance seems to do what I want. Cheers Ben

On 2019-08-02 5:38 p.m., Benjamin Franksen wrote: But I could not find the |instance Monoid a => Monad ((,) a)| documented anywhere in the base package. If you look at the list of instances under the definition of |Monad|, you’ll see |Monoid a => Monad ((,) a)| | /Since: 4.9.0.0/ in the list. Clicking on the |# Source| link takes you to the source of |GHC.Base|: |instance Monoid a => Monad ((,) a) where (u, a) >>= k = case k a of (v, b) -> (u <> v, b) |

Am 03.08.19 um 01:48 schrieb Neil Mayhew:
On 2019-08-02 5:38 p.m., Benjamin Franksen wrote:
But I could not find the
|instance Monoid a => Monad ((,) a)|
documented anywhere in the base package.
If you look at the list of instances under the definition of |Monad|, you’ll see |Monoid a => Monad ((,) a)| | /Since: 4.9.0.0/ in the list. Clicking on the |# Source| link takes you to the source of |GHC.Base|:
|instance Monoid a => Monad ((,) a) where (u, a) >>= k = case k a of (v, b) -> (u <> v, b) |
Thanks! No idea how/why I missed that. I have stared at that list for quite some time before sending my question, just couldn' see it... And yes, this is exactly the instance I had in mind (with Any instead of Bool). Cheers Ben

Hi, I think the error message says there is no Monoid for Bool. It is
because Bool can be monoid by either || or && operations, which would lead
to ambiguity if Bool is monoid by default.
You can:
1. use Maybe Unit instead
2. (overkill) Define AndMonoid Bool newtype and use DeriveVia and coerce
On Fri, Aug 2, 2019 at 7:39 PM Benjamin Franksen
I wanted to define a simple Monad instance for (Bool,) as
instance Monad ((,) Bool) where return x = (False, x) (True, x) >>= k = (True, snd (k x)) (False, x) >>= k = k x -- or: (b, x) >>= k = let (c, y) = k x in (b||c, y)
The idea was to keep track of whether functions change their input value or not.
To my astonishment I found that this definition overlaps with an existing one. GHC tells me
x.hs:2:10: error: • No instance for (Monoid Bool) arising from the superclasses of an instance declaration • In the instance declaration for ‘Monad ((,) Bool)’ | 2 | instance Monad ((,) Bool) where | ^^^^^^^^^^^^^^^^
x.hs:2:10: error: • Overlapping instances for Monad ((,) Bool) arising from a use of ‘GHC.Base.$dm>>’ Matching instances: instance Monoid a => Monad ((,) a) -- Defined in ‘GHC.Base’ instance Monad ((,) Bool) -- Defined at x.hs:2:10 • In the expression: GHC.Base.$dm>> @((,) Bool) In an equation for ‘>>’: (>>) = GHC.Base.$dm>> @((,) Bool) In the instance declaration for ‘Monad ((,) Bool)’ | 2 | instance Monad ((,) Bool) where | ^^^^^^^^^^^^^^^^
[one more similar overlap error elided]
But I could not find the
instance Monoid a => Monad ((,) a)
documented anywhere in the base package. Should I look harder? Or is this instance accidentally leaking from GHC.Base?
Eventually, through some experimenting I found that if I replace Bool with Any, then the existing instance seems to do what I want.
Cheers Ben
_______________________________________________ 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.

Bool is also a monoid under xor.
On Mon, Aug 5, 2019, 4:34 PM Jinxuan Zhu
Hi, I think the error message says there is no Monoid for Bool. It is because Bool can be monoid by either || or && operations, which would lead to ambiguity if Bool is monoid by default.
You can: 1. use Maybe Unit instead 2. (overkill) Define AndMonoid Bool newtype and use DeriveVia and coerce
On Fri, Aug 2, 2019 at 7:39 PM Benjamin Franksen
wrote: I wanted to define a simple Monad instance for (Bool,) as
instance Monad ((,) Bool) where return x = (False, x) (True, x) >>= k = (True, snd (k x)) (False, x) >>= k = k x -- or: (b, x) >>= k = let (c, y) = k x in (b||c, y)
The idea was to keep track of whether functions change their input value or not.
To my astonishment I found that this definition overlaps with an existing one. GHC tells me
x.hs:2:10: error: • No instance for (Monoid Bool) arising from the superclasses of an instance declaration • In the instance declaration for ‘Monad ((,) Bool)’ | 2 | instance Monad ((,) Bool) where | ^^^^^^^^^^^^^^^^
x.hs:2:10: error: • Overlapping instances for Monad ((,) Bool) arising from a use of ‘GHC.Base.$dm>>’ Matching instances: instance Monoid a => Monad ((,) a) -- Defined in ‘GHC.Base’ instance Monad ((,) Bool) -- Defined at x.hs:2:10 • In the expression: GHC.Base.$dm>> @((,) Bool) In an equation for ‘>>’: (>>) = GHC.Base.$dm>> @((,) Bool) In the instance declaration for ‘Monad ((,) Bool)’ | 2 | instance Monad ((,) Bool) where | ^^^^^^^^^^^^^^^^
[one more similar overlap error elided]
But I could not find the
instance Monoid a => Monad ((,) a)
documented anywhere in the base package. Should I look harder? Or is this instance accidentally leaking from GHC.Base?
Eventually, through some experimenting I found that if I replace Bool with Any, then the existing instance seems to do what I want.
Cheers Ben
_______________________________________________ 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.

When this question came up the other day I started to wonder how many boolean operators are monoidal. I wrote a program to check. There are eight associative operators (i.e. that give rise to semigroups). They are const True or const flip const xnor and xor const False Only four of these have an identity (i.e. give rise to monoids). They are or xnor and xor Tom
putStrLn showMonoids Semigroups TT=T TF=T FT=T FF=T TT=T TF=T FT=T FF=F TT=T TF=T FT=F FF=F TT=T TF=F FT=T FF=F TT=T TF=F FT=F FF=T TT=T TF=F FT=F FF=F TT=F TF=T FT=T FF=F TT=F TF=F FT=F FF=F Monoids TT=T TF=T FT=T FF=F TT=T TF=F FT=F FF=T TT=T TF=F FT=F FF=F TT=F TF=T FT=T FF=F
allOfThem :: [Bool] allOfThem = [True, False] binops :: [Bool -> Bool -> Bool] binops = do tt <- allOfThem tf <- allOfThem ft <- allOfThem ff <- allOfThem let f True True = tt f True False = tf f False True = ft f False False = ff pure f associative :: (Bool -> Bool -> Bool) -> Bool associative (.*) = and $ do x <- allOfThem y <- allOfThem z <- allOfThem pure (x .* (y .* z) == (x .* y) .* z) identity :: (Bool -> Bool -> Bool) -> Bool identity (.*) = or $ do i <- allOfThem return (and $ do x <- allOfThem [x .* i == x, i .* x == x]) semigroups :: [Bool -> Bool -> Bool] semigroups = filter associative binops monoids :: [Bool -> Bool -> Bool] monoids = filter identity semigroups showBool :: Bool -> String showBool True = "T" showBool False = "F" showBinop :: (Bool -> Bool -> Bool) -> String showBinop (.*) = unwords $ do x <- allOfThem y <- allOfThem pure (showBool x ++ showBool y ++ "=" ++ showBool (x .* y)) showMonoids :: String showMonoids = (unlines . concat) [ ["Semigroups"] , map showBinop semigroups , ["Monoids"] , map showBinop monoids ] On Mon, Aug 05, 2019 at 04:49:41PM -0400, David Feuer wrote:
Bool is also a monoid under xor.
On Mon, Aug 5, 2019, 4:34 PM Jinxuan Zhu
wrote: Hi, I think the error message says there is no Monoid for Bool. It is because Bool can be monoid by either || or && operations, which would lead to ambiguity if Bool is monoid by default.
You can: 1. use Maybe Unit instead 2. (overkill) Define AndMonoid Bool newtype and use DeriveVia and coerce
On Fri, Aug 2, 2019 at 7:39 PM Benjamin Franksen
wrote: I wanted to define a simple Monad instance for (Bool,) as
instance Monad ((,) Bool) where return x = (False, x) (True, x) >>= k = (True, snd (k x)) (False, x) >>= k = k x -- or: (b, x) >>= k = let (c, y) = k x in (b||c, y)
The idea was to keep track of whether functions change their input value or not.
To my astonishment I found that this definition overlaps with an existing one. GHC tells me
x.hs:2:10: error: • No instance for (Monoid Bool) arising from the superclasses of an instance declaration • In the instance declaration for ‘Monad ((,) Bool)’ | 2 | instance Monad ((,) Bool) where | ^^^^^^^^^^^^^^^^
x.hs:2:10: error: • Overlapping instances for Monad ((,) Bool) arising from a use of ‘GHC.Base.$dm>>’ Matching instances: instance Monoid a => Monad ((,) a) -- Defined in ‘GHC.Base’ instance Monad ((,) Bool) -- Defined at x.hs:2:10 • In the expression: GHC.Base.$dm>> @((,) Bool) In an equation for ‘>>’: (>>) = GHC.Base.$dm>> @((,) Bool) In the instance declaration for ‘Monad ((,) Bool)’ | 2 | instance Monad ((,) Bool) where | ^^^^^^^^^^^^^^^^
[one more similar overlap error elided]
But I could not find the
instance Monoid a => Monad ((,) a)
documented anywhere in the base package. Should I look harder? Or is this instance accidentally leaking from GHC.Base?
Eventually, through some experimenting I found that if I replace Bool with Any, then the existing instance seems to do what I want.

On 2019-08-05 2:33 p.m., Jinxuan Zhu wrote: … Bool can be monoid by either || or && operations, which would lead to ambiguity if Bool is monoid by default. You can: 1. use Maybe Unit instead 2. (overkill) Define AndMonoid Bool newtype and use DeriveVia and coerce |Data.Monoid| from |base| already has |Any| and |All| for this.

There are All and Any Monoids in Data.Monoid Sent from my iPhone
On 5 Aug 2019, at 23.33, Jinxuan Zhu
wrote: Hi, I think the error message says there is no Monoid for Bool. It is because Bool can be monoid by either || or && operations, which would lead to ambiguity if Bool is monoid by default.
You can: 1. use Maybe Unit instead 2. (overkill) Define AndMonoid Bool newtype and use DeriveVia and coerce
On Fri, Aug 2, 2019 at 7:39 PM Benjamin Franksen
wrote: I wanted to define a simple Monad instance for (Bool,) as instance Monad ((,) Bool) where return x = (False, x) (True, x) >>= k = (True, snd (k x)) (False, x) >>= k = k x -- or: (b, x) >>= k = let (c, y) = k x in (b||c, y)
The idea was to keep track of whether functions change their input value or not.
To my astonishment I found that this definition overlaps with an existing one. GHC tells me
x.hs:2:10: error: • No instance for (Monoid Bool) arising from the superclasses of an instance declaration • In the instance declaration for ‘Monad ((,) Bool)’ | 2 | instance Monad ((,) Bool) where | ^^^^^^^^^^^^^^^^
x.hs:2:10: error: • Overlapping instances for Monad ((,) Bool) arising from a use of ‘GHC.Base.$dm>>’ Matching instances: instance Monoid a => Monad ((,) a) -- Defined in ‘GHC.Base’ instance Monad ((,) Bool) -- Defined at x.hs:2:10 • In the expression: GHC.Base.$dm>> @((,) Bool) In an equation for ‘>>’: (>>) = GHC.Base.$dm>> @((,) Bool) In the instance declaration for ‘Monad ((,) Bool)’ | 2 | instance Monad ((,) Bool) where | ^^^^^^^^^^^^^^^^
[one more similar overlap error elided]
But I could not find the
instance Monoid a => Monad ((,) a)
documented anywhere in the base package. Should I look harder? Or is this instance accidentally leaking from GHC.Base?
Eventually, through some experimenting I found that if I replace Bool with Any, then the existing instance seems to do what I want.
Cheers Ben
_______________________________________________ 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.
participants (7)
-
Ben Franksen
-
Benjamin Franksen
-
David Feuer
-
Jinxuan Zhu
-
Neil Mayhew
-
Oleg Grenrus
-
Tom Ellis