[Haskell-cafe] Problem with overlapping class instances

Graham Klyne gk at ninebynine.org
Tue Nov 23 11:25:07 EST 2004


At 16:16 23/11/04 +0000, Keean Schupke wrote:
>The problem is that (cw c) overlaps with String. It will still ovarlap if 
>you use data decl.
>it is the CW that needs to be a datatype. See Below:

Thanks.  I've massaged that into something that compiles (copy below).

I think I see why this works, but I still can't say that I find the
revised structure entirely intuitive.   I think the key feature is that
wrapped instances of ConceptExpr are distinguished from "native" instances
by the type constructor CW.  That is, each instance type is distinguished
by different known type constructor -- in this case, [] and CW.

I need to noodle on the a while to see if the pattern fits my application,
but I think I get the general idea.  Of all the combinations I thought about
making the type constructor part of the class method signatures was not
one I'd tried.

Also, I think declaring CW as a 'newtype' rather than 'data'
captures the intent more directly.

#g
--

spike-overlap-ConceptExpr-datatyped.lhs
---------------------------------------

Some given type and class declarations:

 > 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
 > type AtomicRole    = String   -- named atomic role

Declare AtomicConcept as "base" instance of ConceptExpr.

 > instance ConceptExpr AtomicConcept where
 >     iConcept = undefined

To allow a common expression to support multiple description logics,
define a wrapper type and class for DLConcept and DLRole:

 > newtype CW cw c = CW cw deriving (Eq,Show)
 > class ConceptWrapper cw c | cw -> c where
 >    wrapConcept :: c -> (CW cw c) -> (CW cw c)
 >    getConcept :: (CW cw c) -> c

Using this, a ConceptWrapper can be defined to be an instance of
ConceptExpr:

 > instance (Eq cw, Show cw, ConceptWrapper cw c,ConceptExpr c) =>
 >     ConceptExpr (CW cw c) where
 >     iConcept i           = iConcept i . getConcept

Now declare a pair containing a ConceptExpr to be an instance of
ConceptWrapper:

 > type Wrap d c = (c,d)
 >
 > instance ConceptWrapper (Wrap d c) c where
 >     wrapConcept c (CW (_,d)) = CW (c,d)
 >     getConcept    (CW (c,_)) = c



------------
Graham Klyne
For email:
http://www.ninebynine.org/#Contact



More information about the Haskell-Cafe mailing list