Created
September 24, 2019 10:05
-
-
Save mrBliss/981b377200ba14c9c65fbb53b770dd84 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{-# LANGUAGE DataKinds #-} | |
{-# LANGUAGE GADTs #-} | |
{-# LANGUAGE KindSignatures #-} | |
{-# LANGUAGE PatternSynonyms #-} | |
{-# LANGUAGE ViewPatterns #-} | |
-- | Type-level index | |
data N = Z | S N | |
-- | Value-level type indexed by type-level index | |
data Nat (n :: N) where | |
Zero :: Nat Z | |
Succ :: Nat n -> Nat (S n) | |
isZero :: Nat n -> Bool | |
isZero Zero = True | |
isZero (Succ _) = False | |
-- | Now let's represent 'Nat' using an 'Int': 'SNat'. | |
newtype SNat (n :: N) = UnsafeInt Int | |
-- Let's define pattern synonyms so we can still write inductive functions | |
-- like before. | |
pattern SZero :: SNat Z | |
pattern SZero = UnsafeInt 0 | |
pattern SSucc :: SNat n -> SNat (S n) | |
pattern SSucc n <- (snatPred -> Just n) where | |
SSucc (UnsafeInt n) = UnsafeInt (succ n) | |
snatPred :: SNat (S n) -> Maybe (SNat n) | |
snatPred (UnsafeInt 0) = Nothing | |
snatPred (UnsafeInt n) = Just (UnsafeInt (pred n)) | |
{-# COMPLETE SZero, SSucc #-} | |
-- But this doesn't compile: | |
isSZero :: SNat n -> Bool | |
isSZero SZero = True | |
isSZero (SSucc n) = False | |
{- | |
• Couldn't match type ‘n’ with ‘'Z’ | |
‘n’ is a rigid type variable bound by | |
the type signature for: | |
isSZero :: forall (n :: N). SNat n -> Bool | |
Expected type: SNat n | |
Actual type: SNat 'Z | |
• In the pattern: SZero | |
In an equation for ‘isSZero’: isSZero SZero = True | |
• Relevant bindings include | |
isSZero :: SNat n -> Bool | |
-} |
kosmikus
commented
Sep 24, 2019
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment