[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