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

Reply via email to