我有一个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,但我无法解决这个问题.
作为一种可怕的拼凑,双重包装和使用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)
| 归档时间: |
|
| 查看次数: |
257 次 |
| 最近记录: |