Skip to content

Instantly share code, notes, and snippets.

@neongreen
Created September 2, 2017 21:38
Show Gist options
  • Save neongreen/ba5d0632f6ed1fc10490f6cee46bee5b to your computer and use it in GitHub Desktop.
Save neongreen/ba5d0632f6ed1fc10490f6cee46bee5b to your computer and use it in GitHub Desktop.
newtype ModularInt s = ModularInt Int
mkModularInt :: forall s . Reifies s Int => Int -> ModularInt s
mkModularInt a = ModularInt (a `mod` modulus)
where
modulus = reflect (Proxy :: Proxy s)
instance Reifies s Int => Num (ModularInt s) where
ModularInt a + ModularInt b = mkModularInt (a + b)
ModularInt a - ModularInt b = mkModularInt (a - b)
ModularInt a * ModularInt b = mkModularInt (a * b)
fromInteger = mkModularInt . fromInteger
withModulus :: Int -> (forall s . Reifies s Int => ModularInt s) -> Int
withModulus modulus modularInt =
reify modulus (\(_ :: Proxy s0) ->
case modularInt :: ModularInt s0 of
ModularInt a -> a)
{-
ghci> withModulus 3 (2 + 3 * 4)
2
ghci> withModulus 5 (2 + 3 * 4)
4
ghci> withModulus 8 (2 + 3 * 4)
6
-}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment