
Once again, the Haskell class system is proving rather subtle for me. On this occasion, I'm getting an overlapping class instance error which I think should be fully disambiguated by the supplied class context. The code below (end of message) is a .lhs file that reproduces the problem in Hugs, with external dependencies from my working codebase stripped out. It should be possible to simply load it (or this whole email) to get the same error: [[ Reading file "D:\Cvs\DEV\HaskellDL\spike-overlap-conceptexpr.lhs": ERROR "D:\Cvs\DEV\HaskellDL\spike-overlap-conceptexpr.lhs":30 - Overlapping inst ances for class "ConceptExpr" *** This instance : ConceptExpr (a b) *** Overlaps with : ConceptExpr AtomicConcept *** Common instance : ConceptExpr [Char] ]] The line referred to as "this instance" is: instance (ConceptWrapper cw c, ConceptExpr c) => ConceptExpr (cw c) where The reported overlapping instance is [Char], which I take to be derived from the type constructor [] applied to type Char, this yielding a form that matches (cw c). But the instance ConceptExpr (cw c) is declared to be dependent on the context ConceptWrapper cw c, which has *not* been declared for the type constructor []. GHCi with -fglasgow-exts is no more informative. What am I missing here? #g -- [Source code follows] spike-overlap-ConceptExpr.lhs -----------------------------
type AtomicConcepts a = [(AtomicConcept,[a] )] type AtomicRoles a = [(AtomicRole ,[(a,a)])]
type TInterpretation a = ([a],AtomicConcepts a,AtomicRoles a)
class (Eq c, Show c) => ConceptExpr c where iConcept :: Ord a => TInterpretation a -> c -> [a]
...
type AtomicConcept = String -- named atomic concept
Declare AtomicConcept and AtomicRole as instances of ConceptExpr and RoleExpr (AtomicRole is used by AL, and including AtomicConcept here for completeness).
instance ConceptExpr AtomicConcept where iConcept = undefined
... To allow a common expression to support multiple description logics, we first define a wrapper class for DLConcept and DLRole:
class ConceptExpr c => ConceptWrapper cw c | cw -> c where wrapConcept :: c -> cw c -> cw c getConcept :: cw c -> c
Using this, a ConceptWrapper can be defined to be an instance of ConceptExpr: This is line 30:
instance (ConceptWrapper cw c, ConceptExpr c) => ConceptExpr (cw c) where iConcept = iConcept . getConcept
Error message: Reading file "D:\Cvs\DEV\HaskellDL\spike-overlap-conceptexpr.lhs": ERROR "D:\Cvs\DEV\HaskellDL\spike-overlap-conceptexpr.lhs":30 - Overlapping inst ances for class "ConceptExpr" *** This instance : ConceptExpr (a b) *** Overlaps with : ConceptExpr AtomicConcept *** Common instance : ConceptExpr [Char] ------------ Graham Klyne For email: http://www.ninebynine.org/#Contact