I have the following class:
class SappState s where
getTable :: s -> SymbolTable
getStack :: s -> Stack Scope
getScopeId :: s -> ScopeNum
getAst :: s -> Program
putTable :: SymbolTable -> s -> s
putStack :: Stack Scope -> s -> s
putScopeId :: ScopeNum -> s -> s
putAst :: Program -> s -> s
And I always show
the data
s that instance this class
with the functions defined in it. So I generalized it with the following code:
instance (SappState s) => Show s where
show st = showT ++ showS ++ showI ++ showA
where
showT = getTable st ++ "\n"
showS = "Scope Stack:\n" ++ getStack st ++ "\n"
showI = "Scope Number:\t" ++ getScopeId st ++ "\n"
showA = getAst st ++ "\n"
but GHC gives me the following error:
SappMonad.hs:87:27:
Illegal instance declaration for `Show s'
(All instance types must be of the form (T a1 ... an)
where a1 ... an are *distinct type variables*,
and each type variable appears at most once in the instance head.
Use -XFlexibleInstances if you want to disable this.)
In the instance declaration for `Show s'
Should I just use the FlexibleInstances
pragma? I don't really understand what it does and if it's the right way or if I should drop the idea of generalizing the Show
instance.
edit
I activated the pragma and it has this new error:
SappMonad.hs:88:10:
Constraint is no smaller than the instance head
in the constraint: SappState s
(Use -XUndecidableInstances to permit this)
In the instance declaration for `Show s'
I activated UndecidableInstances
too and now a simple deriving Show
will break:
data Architecture = Arch
{ archName :: String
, types :: Map.Map DataType Bytes
} deriving (Show)
throws the following error:
SappMonad.hs:39:17:
Overlapping instances for Show (Map.Map DataType Bytes)
arising from the 'deriving' clause of a data type declaration
Matching instances:
instance (Show k, Show a) => Show (Map.Map k a)
-- Defined in `containers-0.5.0.0:Data.Map.Base'
instance SappState s => Show s -- Defined at SappMonad.hs:89:10
When deriving the instance for (Show Architecture)
second edit
I googled some more in the subject and found OverlappingInstances
, added the pragma and it compiles and I think it works correctly. But I feel I'm going too far with these language extensions. How could I stop using some of them and still get the same functionality?