Hi,

I'm trying to set up some operators for applicative versions of prelude types. For instance:

-- | Applicative Equality.
class (Eq a) => AppEq f a where
  (.==.), (./=.) :: f a -> f a -> f Bool

instance (Applicative f, Eq a) => AppEq f a where
  (.==.)  = liftA2 (==)
  (./=.)  = liftA2 (/=)


Hopefully the intention is fairly straightforward: if "f" is an instance of Applicative then the lifted implementation of the underlying type. Otherwise I can just give my own instance, which is useful for things that "wrap" prelude types but where "fmap" doesn't work. For instance:

data (Ord a) => Interval a = Interval a a

instance (Ord a) => AppEq Interval a where
  i1@(Interval _ u1) .==. i2@(Interval _ u2)
      | isSingleton i1 && isSingleton i2 && u1 == u2  = Interval True True
      | has i1 u2 || has i2 u1                        = Interval False True
| otherwise = Interval False False i1 ./=. i2 = let Interval b1 b2 = (i1 .==. i2) in Interval (not b2) (not b1)

isSingleton :: (Ord a) => Interval a -> Bool
isSingleton (Interval lower upper) = lower == upper

has :: (Ord a) => Interval a -> a -> Bool
has (Interval lower upper) v = v >= lower && v <= upper


You can't (easily) define fmap for Interval because the function given as an argument might not be monotonic. So instead you have to write custom implementations for each lifted function, as shown here for (.==.) and (./=.) . The same principle works for AppOrd, AppNum etc, but I'm trying to solve the problem for just AppEq for now.

This compiles, but when I try to use it I get this in ghci:

*Interval> let i1 = Interval 4 5
*Interval> let i2 = Interval 4 6
*Interval> i1 .==. i2

<interactive>:1:0:
   Overlapping instances for AppEq Interval Integer
     arising from a use of `.==.' at <interactive>:1:0-9
   Matching instances:
     instance (Ord a) => AppEq Interval a
       -- Defined at Interval.hs:(22,0)-(27,78)
     instance (Control.Applicative.Applicative f, Eq a) => AppEq f a
       -- Defined at AppPrelude.hs:(32,0)-(34,23)
   In the expression: i1 .==. i2
   In the definition of `it': it = i1 .==. i2

I'm puzzled, because Interval is not an instance of Applicative, so the second instance doesn't apply. Can anyone help me out?

I'm using ghc 6.8.3, so its possible that this was a bug fixed in 6.10.

Paul.
_______________________________________________
Haskell-Cafe mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to