Modular arithmetic
Dylan Thurston
dpt@math.harvard.edu
Tue, 21 Aug 2001 03:35:02 -0400
They said it couldn't be done! They said Haskell didn't have
dependent types!
Here's a way to mimic dependent types using existential types,
illustrated by an implementation of modular arithmetic. To try it
out, load modulus.hs and try something like
Modulus> inModulus (mkModulus (1234567890123::Integer)) (^98765432198765) 2
1160454313058
to compute 2 to the 98765432198765'th power modulo 1234567890123.
The key is the definitions at the top of TypeVal.hs:
> class TypeVal a t | t -> a where
> -- typeToVal should ignore its argument.
> typeToVal :: t -> a
>
> data Wrapper a = forall t . (TypeVal a t) => Wrapper t
>
> class ValToType a where
> valToType :: a -> Wrapper a
`valToType' takes a value `x' and returns a (wrapped version of a)
fake value in a new type; from the new type, `x' can be recovered by
applying typeToVal.
This code works under ghc. It uses existentially quantified data
constructors, scoped type variables, and explicit universal
quantification.
Enjoy,
Dylan Thurston