fork download
  1. {-# LANGUAGE ScopedTypeVariables, EmptyDataDecls #-}
  2. import Data.Function
  3. data Zero
  4. data Succ a
  5.  
  6. class Nat a where
  7. toInt::a->Int
  8.  
  9. instance Nat Zero where
  10. toInt = const 0
  11.  
  12. instance (Nat a) => Nat (Succ a) where
  13. toInt = const $ toInt (undefined::a) + 1
  14.  
  15.  
  16. type One = Succ Zero
  17. type Two = Succ One
  18. type Three = Succ Two
  19. type Four = Succ Three
  20. type Five = Succ Four
  21.  
  22. data ModNInt mod = MN {int::Int} deriving ( Eq, Ord)
  23.  
  24. instance Show (ModNInt mod) where
  25. show = show . int
  26.  
  27. instance (Nat mod) => Enum (ModNInt mod) where
  28. toEnum = MN . (`mod` toInt (undefined::mod))
  29. fromEnum = int
  30.  
  31. convop2 p x y = toEnum $ (p `on` fromEnum) x y
  32.  
  33. instance (Nat mod) => Num (ModNInt mod) where
  34. (+) = convop2 (+)
  35. (-) = convop2 (-)
  36. (*) = convop2 (*)
  37.  
  38. a = fromInteger 2 :: ModNInt Five
  39. b = fromInteger 3 :: ModNInt Five
  40. c = fromInteger 19 :: ModNInt Five
  41. main = print [a-b, a*b, a+b-c]
Success #stdin #stdout 0s 5700KB
stdin
Standard input is empty
stdout
[4,1,1]