我遇到UndecidableInstances
问题但我无法弄清楚如何避免使用newtype
。这是我原来的:
{-# 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
我得到的信息是
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)'
我想避免使用UndecidableInstances
,因为此代码将位于可重用的库中,因此我尝试声明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
但我得到同样的错误。我已经在UndecidableInstances
上阅读了其他问题的答案,但我还没有能够解决这个问题。
答案 0 :(得分:1)
作为一个可怕的kludge,双重包装并使用FlexibleInstances
似乎可以解决问题:
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