不可判断的实体和新类型

mhw*_*bat 7 haskell

我有一个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
Run Code Online (Sandbox Code Playgroud)

我得到的信息是

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)'
Run Code Online (Sandbox Code Playgroud)

我想避免,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
Run Code Online (Sandbox Code Playgroud)

但我得到了同样的错误.我已经阅读了其他问题的答案UndecidableInstances,但我无法解决这个问题.

Cac*_*tus 1

作为一种可怕的拼凑,双重包装和使用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
Run Code Online (Sandbox Code Playgroud)