Hugs does support scoped type variables bound by *type sigs in patterns*, but not by class or instance declarations. So when you say (maxBound :: b) you are really saying (maxBound :: forall b. b) and it's that universal quantification that has no Bounded b context.
That's why you need -fglasgow-exts to compile it with GHC, to get the scoped type variables. I've gotten so used to scoped type variables that I couldn't see why it wasn't Haskell 98, until I tried to compile without -fglasgow-exts. Then GHC says Key.hs:99: Could not deduce (Bounded b) from the context () arising from use of `maxBound' at Key.hs:99 Probable fix: Add (Bounded b) to the expected type of an expression When checking the type signature of the expression: maxBound :: forall b. b which does at least point to the error. Simon | -----Original Message----- | From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Dominic | Steinitz | Sent: 02 October 2004 12:04 | To: [EMAIL PROTECTED] | Subject: [Haskell] GHC / Hugs Disagree on Constraints | | GHC accepts this with -fglasgow-exts | | instance (Ord a, Bits a, Bounded a, Integral a, LargeWord a, | Bits b, Bounded b, Integral b, LargeWord b) => | Bounded (LargeKey a b) where | minBound = 0 | maxBound = | fromIntegral $ | (1 + fromIntegral (maxBound::b))* | (1 + fromIntegral (maxBound::a)) - 1 | | Hugs rejects it with +N -98 with | | ERROR "Codec/Encryption/LargeKey.hs":94 - Cannot justify constraints in | type annotation | *** Expression : maxBound | *** Type : b | *** Given context : () | *** Constraints : Bounded b | | Since I've already declared b to be Bounded, it looks like a bug in Hugs. | | Dominic. | | =============================================================== | ======== | | module Codec.Encryption.LargeKey | (Word128,Word192,Word256,LargeWord) where | | import Data.Word | import Data.Bits | import Numeric | import Char | | -- Keys have certain capabilities. | | class LargeWord a where | largeWordToInteger :: a -> Integer | integerToLargeWord :: Integer -> a | largeWordPlus :: a -> a -> a | largeWordAnd :: a -> a -> a | largeWordOr :: a -> a -> a | largeWordShift :: a -> Int -> a | largeWordXor :: a -> a -> a | largeBitSize :: a -> Int | | -- Word64 is a key in the obvious way. | | instance LargeWord Word64 where | largeWordToInteger = toInteger | integerToLargeWord = fromInteger | largeWordPlus = (+) | largeWordAnd = (.&.) | largeWordOr = (.|.) | largeWordShift = shift | largeWordXor = xor | largeBitSize = bitSize | | -- Define larger keys from smaller ones. | | data LargeKey a b = LargeKey a b | deriving (Eq, Ord) | | instance (Ord a, Bits a, LargeWord a, Bits b, LargeWord b) => | LargeWord (LargeKey a b) where | largeWordToInteger (LargeKey lo hi) = | largeWordToInteger lo + (2^(bitSize lo)) * largeWordToInteger hi | integerToLargeWord x = | let (h,l) = x `quotRem` (2^(bitSize lo)) | (lo,hi) = (integerToLargeWord l, integerToLargeWord h) in | LargeKey lo hi | largeWordPlus (LargeKey alo ahi) (LargeKey blo bhi) = | LargeKey lo' hi' where | lo' = alo + blo | hi' = ahi + bhi + if lo' < alo then 1 else 0 | largeWordAnd (LargeKey alo ahi) (LargeKey blo bhi) = | LargeKey lo' hi' where | lo' = alo .&. blo | hi' = ahi .&. bhi | largeWordOr (LargeKey alo ahi) (LargeKey blo bhi) = | LargeKey lo' hi' where | lo' = alo .|. blo | hi' = ahi .|. bhi | largeWordOr (LargeKey alo ahi) (LargeKey blo bhi) = | LargeKey lo' hi' where | lo' = alo .|. blo | hi' = ahi .|. bhi | largeWordXor (LargeKey alo ahi) (LargeKey blo bhi) = | LargeKey lo' hi' where | lo' = alo `xor` blo | hi' = ahi `xor` bhi | largeWordShift w 0 = w | largeWordShift (LargeKey lo hi) x = | if bitSize lo < bitSize hi | then LargeKey (shift lo x) | (shift hi x .|. (shift (conv lo) (x - | (bitSize lo)))) | else LargeKey (shift lo x) | (shift hi x .|. (conv $ shift lo (x - | (bitSize lo)))) | where conv = integerToLargeWord . largeWordToInteger | largeBitSize ~(LargeKey lo hi) = largeBitSize lo + largeBitSize hi | | instance (Ord a, Bits a, LargeWord a, Bits b, LargeWord b) => Show | (LargeKey a b) where | showsPrec p = showInt . largeWordToInteger | | instance (Ord a, Bits a, LargeWord a, Bits b, LargeWord b) => | Num (LargeKey a b) where | (+) = largeWordPlus | fromInteger = integerToLargeWord | | -- Larger keys are instances of Bits provided their constituents are keys. | | instance (Ord a, Bits a, LargeWord a, Bits b, LargeWord b) => | Bits (LargeKey a b) where | (.&.) = largeWordAnd | (.|.) = largeWordOr | xor = largeWordXor | shift = largeWordShift | bitSize = largeBitSize | | instance (Ord a, Bits a, Bounded a, Integral a, LargeWord a, | Bits b, Bounded b, Integral b, LargeWord b) => | Bounded (LargeKey a b) where | minBound = 0 | maxBound = | fromIntegral $ | (1 + fromIntegral (maxBound::b))* | (1 + fromIntegral (maxBound::a)) - 1 | | instance (Ord a, Bits a, LargeWord a, Ord b, Bits b, LargeWord b) => | Integral (LargeKey a b) where | toInteger = largeWordToInteger | | instance (Ord a, Bits a, LargeWord a, Ord b, Bits b, LargeWord b) => | Real (LargeKey a b) | | instance Enum (LargeKey a b) | | type Word96 = LargeKey Word32 Word64 | type Word128 = LargeKey Word64 Word64 | type Word160 = LargeKey Word32 Word128 | type Word192 = LargeKey Word64 Word128 | type Word224 = LargeKey Word32 Word192 | type Word256 = LargeKey Word64 Word192 | _______________________________________________ | Haskell mailing list | [EMAIL PROTECTED] | http://www.haskell.org/mailman/listinfo/haskell _______________________________________________ Haskell mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell