[Haskell-cafe] Re: overlapping instances,
selecting if type a does not belong to class?
oleg at pobox.com
oleg at pobox.com
Wed Feb 28 01:15:56 EST 2007
The problem you report can be fixed with some trickery and local
functional dependencies. I'd like to show a different solution, which
follows a useful general pattern, of isolating overlapping instances
to one small part of the program that analyzes the type. The rest of
the type program just uses the results of the analysis.
> I wasn't able to find the definition of AllOf(But):
It is in the complete code
http://pobox.com/~oleg/ftp/Haskell/poly2.hs
It isn't that interesting:
> data AllOfBut x y
{-# OPTIONS -fglasgow-exts #-}
{-# OPTIONS -fallow-undecidable-instances #-}
{-# OPTIONS -fallow-overlapping-instances #-}
module HAA where
import HListPrelude
data HTrue
data HFalse
-- If two arguments are HList's, concatenate them. If only one of them
-- is HList, add the other to the head. We assume at least one is an HList.
class IsHList a b | a -> b
instance IsHList HNil HTrue
instance IsHList (HCons a b) HTrue
instance TypeCast HFalse y => IsHList x y
-- The are no overlapping instances below
class (HList c) => HListAppendArbitrary a b c | a b -> c where
hAppendArbitrary :: a -> b -> c
instance (IsHList a af, IsHList b bf, HAA af bf a b c)
=> HListAppendArbitrary a b c where
hAppendArbitrary = haa (undefined::af) (undefined::bf)
class (HList c) => HAA af bf a b c | af bf a b -> c where
haa :: af -> bf -> a -> b -> c
-- Both are HLists
instance (HList c, HAppend a b c) => HAA HTrue HTrue a b c where
haa _ _ = hAppend
instance HList a => HAA HTrue HFalse a b (HCons b a) where
haa _ _ a b = HCons b a
instance HList b => HAA HFalse HTrue a b (HCons a b) where
haa _ _ a b = HCons a b
-- deliberately unimplemented: at least one must be an HList...
-- instance HList b => HAA HFalse HFalse a b c where
test1 = hAppendArbitrary HNil True
test2 = hAppendArbitrary True (HCons () HNil)
test3 = hAppendArbitrary (HCons () HNil) (HCons False HNil)
test4 = hAppendArbitrary (HCons () HNil) 'a'
-- testf = hAppendArbitrary 'n' ()
-- TypeCast is skipped
More information about the Haskell-Cafe
mailing list