2014-04-22 1 views
7

मेरे पास UndecidableInstances समस्या है कि मैं यह समझने में सक्षम नहीं हूं कि newtype का उपयोग करने से कैसे बचें। यहाँ है कि मैं क्या मूल रूप से किया था है:UndecidableInstances और newtypes

{-# 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

क्यों वास्तव में आप नहीं चाहते कि 'UndecidableInstances'? उस बारे में बहुत बुरा नहीं है। – leftaroundabout

+0

यदि यहां उपयोग करना ठीक है, तो यह भव्य है। मैंने सोचा कि मुझे इस तरह की पोस्टों के कारण इसे टालना चाहिए: https://lukepalmer.wordpress.com/2008/04/08/stop-using-undecidable-instances/ – mhwombat

+1

यह बिल्कुल ठीक है, जब तक आप नहीं करेंगे कुछ 'ब्रह्मांड' के आधार पर 'रिकॉर्ड' उदाहरण परिभाषित करना शुरू करें। – leftaroundabout

उत्तर

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 
संबंधित मुद्दे