[Haskell-beginners] Overlapping instances problem

Baa aquagnu at gmail.com
Fri Dec 1 14:10:57 UTC 2017


Thanks, I got it. So I workarounded the problem with newtypes (all
"default" instances are for newtypes, my types are wrapping in those
newtypes).

===
Best regards, Paul

> What happens if type 'a' is both an instance EnumTag and StrTag at
> the same time?  Then which instance does it choose?  You may know
> that can't happen in your code, but there's no guarantee that someone
> using your library or that some import won't bring such a type into
> scope.
> 
> Because of this ambiguity, during type checking haskell ignores class
> contexts and merely looks at the instance head (Read a), and says hey
> there are two instances 'Read a', they are overlapping.
> 
> As to what to do about it, I'm not sure.  But I don't think I would be
> trying to get different read instances based on whatever typeclasses
> happen to be in scope for that type.
> 
> On Fri, Dec 1, 2017 at 6:57 AM, Baa <aquagnu at gmail.com> wrote:
> 
> > Hello, List!
> >
> > I got error:
> >
> >  Duplicate instance declarations:
> >    instance [overlap ok] EnumTag a => Read a
> >      -- Defined at /XXX/intero/intero2932Xpa-TEMP.hs:110:27
> >    instance [overlap ok] StrTag a => Read a
> >      -- Defined at /XXX/intero/intero2932Xpa-TEMP.hs:121:27 (intero)
> >
> > For this code:
> >
> >   class (Show a, Enum a) => EnumTag a where
> >     anyEnum :: a
> >
> >   instance {-# OVERLAPS #-} EnumTag a => Read a where
> >     readPrec = RP.lift P.skipSpaces >> expectEnum
> >   instance {-# OVERLAPS #-} EnumTag a => Eq a where
> >     a == b | a == anyEnum || b == anyEnum = True
> >           | otherwise = fromEnum a == fromEnum b
> >
> >   class StrTag a where
> >     anyStr :: a
> >     tagPrefix :: a -> String -- ^ should be constant
> >     toStr :: String -> a
> >
> >   instance {-# OVERLAPS #-} StrTag a => Read a where
> >     readPrec = parens $ do
> >       RP.lift P.skipSpaces
> >       (RP.lift $ expectShown anyStr) <++ RP.lift g
> >       where g = do
> >               Just s@(_:_) <- L.stripPrefix tagPrefix <$> expectTag
> >               return $ toStr s
> >
> > Why does it happen? `Read a` in 1st instance is valid only when a is
> > `EnumTag`, in 2nd one - is valid only when a is `StrTag`.
> >
> > How can I fix this error and to create "default" instances for
> > `EnumTag` and to `StrTag`, so client code will "inherit" those
> > functionality (`Read`) simple, only with instantiation of `EnumTag`
> > or `StrTag` ?
> >
> > Sure, if I comment `instance ... StrTag a` then all work fine, but
> > I need 2 specialized `Read`s (and `Eq`s too :)
> >
> > ===
> > Best regards, Paul
> > _______________________________________________
> > Beginners mailing list
> > Beginners at haskell.org
> > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
> >  



More information about the Beginners mailing list