I have an UndecidableInstances
problem that I haven't been able to figure out how to avoid using newtype
. Here's what I had originally:
{-# LANGUAGE TypeFamilies, FlexibleContexts #-}
class Record r where
key :: r -> String
class (Record r) => SizedRecord r where
size :: r -> Int
class Database d where
type DBRecord d
class (Record a) => Agent a where
agentId :: a -> String
agentId = key
class (Database (UAgentDB u), Agent (UAgent u), Record (UAgent u))
=> Universe u where
type UAgent u
type UAgentDB u
-- plus other stuff
data SimpleUniverse d = SimpleUniverse
{
suDB :: d
-- plus other stuff
} deriving (Show, Eq)
instance (Record (DBRecord d)) => Universe (SimpleUniverse d) where -- line 28
type UAgent (SimpleUniverse d) = DBRecord d
type UAgentDB (SimpleUniverse d) = d
-- plus other stuff
The message I get is
amy9.hs:28:10:
Constraint is no smaller than the instance head
in the constraint: Record (DBRecord d)
(Use -XUndecidableInstances to permit this)
In the instance declaration for `Universe (SimpleUniverse d)'
I want to avoid UndecidableInstances
because this code is going to be in a reusable library, so I try declaring a newtype
:
newtype SimpleUniverse2 u = SimpleUniverse2 { fromAdditiveGroup :: u }
instance (Record (DBRecord u)) => Universe (SimpleUniverse2 u) where
type UAgent (SimpleUniverse2 u) = DBRecord u
type UAgentDB (SimpleUniverse2 u) = u
-- plus other stuff
But I get the same error. I've read answers to other questions on UndecidableInstances
, but I haven't been able to solve this.
As a horrible kludge, double-wrapping and using FlexibleInstances
seem to do the trick:
import Control.Monad.Identity
instance (Database u, Agent (DBRecord u), Record (DBRecord u)) =>
Universe (Identity (Identity u)) where
type UAgent (Identity (Identity u)) = DBRecord u
type UAgentDB (Identity (Identity u)) = u
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With