[Haskell-cafe] instance Monoid a => Monad ((,) a)
Benjamin Franksen
ben.franksen at online.de
Fri Aug 2 23:38:38 UTC 2019
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
More information about the Haskell-Cafe
mailing list