{-# LANGUAGE GADTs, Rank2Types #-}
data Z = Z
data S n = S n
data LT = LT
data GT = GT
data EQ = EQ
LtZ
:: Nat m
=> S m
-> Ordering Z
(S m
) LT
GtZ
:: Nat n
=> S n
-> Ordering (S n
) Z GT
data SomeOrdering n m
= forall o
. SomeOrdering
(Ordering n m o
)
data IsZero n where
IsZero :: IsZero Z
NotZero :: Nat n => S n -> IsZero (S n)
class Nat n where
isZero :: n -> IsZero n
compare :: Nat m
=> n
-> m
-> SomeOrdering n m
instance Nat Z where
toInt _ = 0
isZero _ = IsZero
case isZero m of
IsZero -> SomeOrdering EqZ
NotZero _ -> SomeOrdering $ LtZ m
instance Nat n => Nat (S n) where
toInt ~(S n) = 1 + toInt n
isZero n = NotZero n
case isZero m of
IsZero -> SomeOrdering $ GtZ (S n)
NotZero ~(S m') ->
case compare n m' of
SomeOrdering o@(LtZ _) -> SomeOrdering (LtS o)
SomeOrdering o@(LtS _) -> SomeOrdering (LtS o)
SomeOrdering o@(GtZ _) -> SomeOrdering (GtS o)
SomeOrdering o@(GtS _) -> SomeOrdering (GtS o)
SomeOrdering EqZ -> SomeOrdering (EqS EqZ)
SomeOrdering o@(EqS _) -> SomeOrdering (EqS o)
reifyInt
:: Int -> (forall n
. Nat n
=> n
-> a
) -> a
reifyInt 0 k = k Z
reifyInt n k = reifyInt (n-1) $ \m -> k (S m)
data Vec n a where
Nil :: Vec Z a
(:::) :: Nat n => a -> Vec n a -> Vec (S n) a
toList :: Vec n a -> [a]
toList Nil = []
toList (x ::: xs) = x : toList xs
fromList :: [a] -> (forall n. Nat n => Vec n a -> b) -> b
fromList [] k = k Nil
fromList (x:xs) k = fromList xs $ \xs' -> k (x ::: xs')
(!!) :: (Nat n
, Nat m
) => Vec m a
-> Ordering n m LT
-> a
(x ::: _) !! (LtZ _) = x
(_ ::: xs) !! (LtS o) = xs !! o
_ !! _ = error "should not happen!"
main = do
reifyInt x $ \n -> fromList xs $ \ls ->
SomeOrdering o
@(LtZ
_) -> print $ ls
!! o
SomeOrdering o
@(LtS
_) -> print $ ls
!! o
ey0jIExBTkdVQUdFIEdBRFRzLCBSYW5rMlR5cGVzICMtfQppbXBvcnQgUHJlbHVkZSBoaWRpbmcgKE9yZGVyaW5nLCBFcSwgY29tcGFyZSwgbGVuZ3RoLCAoISEpKQoKZGF0YSBaID0gWgpkYXRhIFMgbiA9IFMgbgoKZGF0YSBMVCA9IExUCmRhdGEgR1QgPSBHVApkYXRhIEVRID0gRVEKCmRhdGEgT3JkZXJpbmcgbiBtIG8gd2hlcmUKICBFcVogOjogT3JkZXJpbmcgWiBaIEVRCiAgRXFTIDo6IChOYXQgbiwgTmF0IG0pID0+IE9yZGVyaW5nIG4gbSBFUSAtPiBPcmRlcmluZyAoUyBuKSAoUyBtKSBFUQogIEx0WiA6OiBOYXQgbSA9PiBTIG0gLT4gT3JkZXJpbmcgWiAoUyBtKSBMVAogIEx0UyA6OiAoTmF0IG4sIE5hdCBtKSA9PiBPcmRlcmluZyBuIG0gTFQgLT4gT3JkZXJpbmcgKFMgbikgKFMgbSkgTFQKICBHdFogOjogTmF0IG4gPT4gUyBuIC0+IE9yZGVyaW5nIChTIG4pIFogR1QKICBHdFMgOjogKE5hdCBuLCBOYXQgbSkgPT4gT3JkZXJpbmcgbiBtIEdUIC0+IE9yZGVyaW5nIChTIG4pIChTIG0pIEdUCmRhdGEgU29tZU9yZGVyaW5nIG4gbSA9IGZvcmFsbCBvLiBTb21lT3JkZXJpbmcgKE9yZGVyaW5nIG4gbSBvKQoKZGF0YSBJc1plcm8gbiB3aGVyZQogIElzWmVybyA6OiBJc1plcm8gWgogIE5vdFplcm8gOjogTmF0IG4gPT4gUyBuIC0+IElzWmVybyAoUyBuKQoKY2xhc3MgTmF0IG4gd2hlcmUKICB0b0ludCA6OiBuIC0+IEludAogIGlzWmVybyA6OiBuIC0+IElzWmVybyBuCiAgY29tcGFyZSA6OiBOYXQgbSA9PiBuIC0+IG0gLT4gU29tZU9yZGVyaW5nIG4gbQoKaW5zdGFuY2UgTmF0IFogd2hlcmUKICB0b0ludCBfID0gMAogIGlzWmVybyBfID0gSXNaZXJvCiAgY29tcGFyZSBfIG0gPQogICAgY2FzZSBpc1plcm8gbSBvZgogICAgICBJc1plcm8gLT4gU29tZU9yZGVyaW5nIEVxWgogICAgICBOb3RaZXJvIF8gLT4gU29tZU9yZGVyaW5nICQgTHRaIG0KaW5zdGFuY2UgTmF0IG4gPT4gTmF0IChTIG4pIHdoZXJlCiAgdG9JbnQgfihTIG4pID0gMSArIHRvSW50IG4KICBpc1plcm8gbiA9IE5vdFplcm8gbgogIGNvbXBhcmUgfihTIG4pIG0gPQogICAgY2FzZSBpc1plcm8gbSBvZgogICAgICBJc1plcm8gLT4gU29tZU9yZGVyaW5nICQgR3RaIChTIG4pCiAgICAgIE5vdFplcm8gfihTIG0nKSAtPgogICAgICAgIGNhc2UgY29tcGFyZSBuIG0nIG9mCiAgICAgICAgICBTb21lT3JkZXJpbmcgb0AoTHRaIF8pIC0+IFNvbWVPcmRlcmluZyAoTHRTIG8pCiAgICAgICAgICBTb21lT3JkZXJpbmcgb0AoTHRTIF8pIC0+IFNvbWVPcmRlcmluZyAoTHRTIG8pCiAgICAgICAgICBTb21lT3JkZXJpbmcgb0AoR3RaIF8pIC0+IFNvbWVPcmRlcmluZyAoR3RTIG8pCiAgICAgICAgICBTb21lT3JkZXJpbmcgb0AoR3RTIF8pIC0+IFNvbWVPcmRlcmluZyAoR3RTIG8pCiAgICAgICAgICBTb21lT3JkZXJpbmcgRXFaIC0+IFNvbWVPcmRlcmluZyAoRXFTIEVxWikKICAgICAgICAgIFNvbWVPcmRlcmluZyBvQChFcVMgXykgLT4gU29tZU9yZGVyaW5nIChFcVMgbykKCnJlaWZ5SW50IDo6IEludCAtPiAoZm9yYWxsIG4uIE5hdCBuID0+IG4gLT4gYSkgLT4gYQpyZWlmeUludCAwIGsgPSBrIFoKcmVpZnlJbnQgbiBrID0gcmVpZnlJbnQgKG4tMSkgJCBcbSAtPiBrIChTIG0pCgpkYXRhIFZlYyBuIGEgd2hlcmUKICBOaWwgOjogVmVjIFogYQogICg6OjopIDo6IE5hdCBuID0+IGEgLT4gVmVjIG4gYSAtPiBWZWMgKFMgbikgYQoKdG9MaXN0IDo6IFZlYyBuIGEgLT4gW2FdCnRvTGlzdCBOaWwgPSBbXQp0b0xpc3QgKHggOjo6IHhzKSA9IHggOiB0b0xpc3QgeHMKCmZyb21MaXN0IDo6IFthXSAtPiAoZm9yYWxsIG4uIE5hdCBuID0+IFZlYyBuIGEgLT4gYikgLT4gYgpmcm9tTGlzdCBbXSBrID0gayBOaWwKZnJvbUxpc3QgKHg6eHMpIGsgPSBmcm9tTGlzdCB4cyAkIFx4cycgLT4gayAoeCA6OjogeHMnKQoKbGVuZ3RoIDo6IFZlYyBuIGEgLT4gbgpsZW5ndGggTmlsID0gWgpsZW5ndGggKF8gOjo6IHhzKSA9IFMgKGxlbmd0aCB4cykKCighISkgOjogKE5hdCBuLCBOYXQgbSkgPT4gVmVjIG0gYSAtPiBPcmRlcmluZyBuIG0gTFQgLT4gYQooeCA6OjogXykgISEgKEx0WiBfKSA9IHgKKF8gOjo6IHhzKSAhISAoTHRTIG8pID0geHMgISEgbwpfICEhIF8gPSBlcnJvciAic2hvdWxkIG5vdCBoYXBwZW4hIgoKbWFpbiA6OiBJTyAoKQptYWluID0gZG8KICB4cyA8LSByZWFkTG4gOjogSU8gW0ludF0KICB4IDwtIHJlYWRMbiA6OiBJTyBJbnQKICByZWlmeUludCB4ICQgXG4gLT4gZnJvbUxpc3QgeHMgJCBcbHMgLT4KICAgIGNhc2UgY29tcGFyZSBuIChsZW5ndGggbHMpIG9mCiAgICAgIFNvbWVPcmRlcmluZyBvQChMdFogXykgLT4gcHJpbnQgJCBscyAhISBvCiAgICAgIFNvbWVPcmRlcmluZyBvQChMdFMgXykgLT4gcHJpbnQgJCBscyAhISBvCiAgICAgIF8gLT4gcHV0U3RyTG4gIm91dCBvZiByYW5nZSEiCg==