[Haskell-cafe] How do I simulate dependent types using phantom types?
Hi, I am trying to implement quadratic fields Q(sqrt d). These are numbers of the form a + b sqrt d, where a and b are rationals, and d is an integer. In an earlier attempt, I tried data QF = QF Integer Rational Rational (see http://www.polyomino.f2s.com/david/haskell/hs/QuadraticField.hs.txt) The problem with this approach is that it's not really type-safe: I can attempt to add a + b sqrt 2 to c + d sqrt 3, whereas this should be a type error because 2 /= 3. So I thought I'd have a go at doing it with phantom types. In effect I'd be using phantom types to simulate dependent types. Here's the code: {-# OPTIONS_GHC -fglasgow-exts #-} import Data.Ratio class IntegerType a where value :: Integer data Two instance IntegerType Two where value = 2 data Three instance IntegerType Three where value = 3 data QF d = QF Rational Rational deriving (Eq) instance IntegerType d = Show (QF d) where show (QF a b) = show a ++ + ++ show b ++ sqrt ++ show value instance IntegerType d = Num (QF d) where QF a b + QF a' b' = QF (a+a') (b+b') negate (QF a b) = QF (-a) (-b) QF a b * QF c d = QF (a*c + b*d*value) (a*d + b*c) fromInteger n = QF (fromInteger n) 0 The problem is, this doesn't work. GHC complains: The class method `value' mentions none of the type variables of the class IntegerType a When checking the class method: value :: Integer In the class declaration for `IntegerType' Is what I'm trying to do reasonable? If no, what should I be doing instead? If yes, why doesn't GHC like it? Thanks, David ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] How do I simulate dependent types using phantom types?
Use value :: a - Integer On 8/18/07, DavidA [EMAIL PROTECTED] wrote: Hi, I am trying to implement quadratic fields Q(sqrt d). These are numbers of the form a + b sqrt d, where a and b are rationals, and d is an integer. In an earlier attempt, I tried data QF = QF Integer Rational Rational (see http://www.polyomino.f2s.com/david/haskell/hs/QuadraticField.hs.txt) The problem with this approach is that it's not really type-safe: I can attempt to add a + b sqrt 2 to c + d sqrt 3, whereas this should be a type error because 2 /= 3. So I thought I'd have a go at doing it with phantom types. In effect I'd be using phantom types to simulate dependent types. Here's the code: {-# OPTIONS_GHC -fglasgow-exts #-} import Data.Ratio class IntegerType a where value :: Integer data Two instance IntegerType Two where value = 2 data Three instance IntegerType Three where value = 3 data QF d = QF Rational Rational deriving (Eq) instance IntegerType d = Show (QF d) where show (QF a b) = show a ++ + ++ show b ++ sqrt ++ show value instance IntegerType d = Num (QF d) where QF a b + QF a' b' = QF (a+a') (b+b') negate (QF a b) = QF (-a) (-b) QF a b * QF c d = QF (a*c + b*d*value) (a*d + b*c) fromInteger n = QF (fromInteger n) 0 The problem is, this doesn't work. GHC complains: The class method `value' mentions none of the type variables of the class IntegerType a When checking the class method: value :: Integer In the class declaration for `IntegerType' Is what I'm trying to do reasonable? If no, what should I be doing instead? If yes, why doesn't GHC like it? Thanks, David ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] How do I simulate dependent types using phantom types?
DavidA wrote: Hi, I am trying to implement quadratic fields Q(sqrt d). These are numbers of the form a + b sqrt d, where a and b are rationals, and d is an integer. ... class IntegerType a where value :: Integer The problem is, this doesn't work. GHC complains: The class method `value' mentions none of the type variables of the class IntegerType a When checking the class method: value :: Integer In the class declaration for `IntegerType' Is what I'm trying to do reasonable? If no, what should I be doing instead? If yes, why doesn't GHC like it? You are on the right track. The problem with the class method is that it doesn't use type 'a' anywhere, consider f :: Integer f = value What class instance should be used here? The solution is to use a dummy parameter: class IntegerType a where value :: a - Integer And call it like: f = value (undefined :: Two) So for instance: instance IntegerType d = Show (QF d) where show (QF a b) = show a ++ + ++ show b ++ sqrt ++ show (value (undefined::d)) The problem is that this doesn't work, because d is not in scope, you need the scoped type variables extension: valueOfQF :: forall a. IntegerType a = QF a - Integer valueOfQF qf = value (undefined :: a) or maybe better, change the class: class IntegerType a where value :: QF a - Integer Now you can simply use instance IntegerType d = Show (QF d) where show qf@(QF a b) = show a ++ + ++ show b ++ sqrt ++ show (value qf) Twan ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe