{-# LANGUAGE FunctionalDependencies,
MultiParamTypeClasses,
FlexibleInstances,
FlexibleContexts,
UndecidableInstances,
ScopedTypeVariables,
OverlappingInstances,
GADTs #-}
data Null
data Succ a
type One = Succ Null
type Two = Succ One
type Three = Succ Two
newtype SafeList l a = SafeList [ a]
nil :: SafeList Null a
nil = SafeList [ ]
cons :: a -> SafeList n a -> SafeList ( Succ n) a
cons a ( SafeList x) = SafeList $ a:x
at
:: ( Less i n
) => SafeList n a
-> LessThanT i
Int -> a
at ( SafeList a) = ( a!! ) . unpack
-- a < b
class Less a b where
instance Less Null ( Succ a)
instance ( Less a b) => Less ( Succ a) ( Succ b)
newtype LessThanT a b
= LessThan b
deriving ( Show ) instance Less ( LessThanT a b) a
unpack ( LessThan x) = x
class Plus a b c | a b -> c where
instance ( Num a
) => Plus Null a a
instance Plus a Null a
instance ( Plus a b c) => Plus ( Succ a) ( Succ b) c
class ToLess a b where
less
:: a
-> Maybe ( LessThanT b a
)
-- Shifting values to the type level isn't fast yet possible
instance ( Num a
, Eq a
) => ToLess a One
where less 0 = Just ( LessThan 0 )
less _ = Nothing
instance ( Num a
, Eq a
, ToLess a b
) => ToLess a
( Succ b
) where less n
= case ( less
$ n
- 1 ) :: Maybe ( LessThanT b a
) of Nothing -> Nothing
Just _ -> Just ( LessThan n)
succ :: ( Num x
) => LessThanT a x
-> LessThanT
( Succ a
) x
succ ( LessThan n
) = LessThan
$ n
+ 1
getAt' :: (i' ~ Succ i, Less i' n) => SafeList n a -> LessThanT i Int -> a
getAt' a i
= at a
$ succ i
main = do
ey0jIExBTkdVQUdFIEZ1bmN0aW9uYWxEZXBlbmRlbmNpZXMsIAogICAgICAgICAgICAgTXVsdGlQYXJhbVR5cGVDbGFzc2VzLCAKICAgICAgICAgICAgIEZsZXhpYmxlSW5zdGFuY2VzLAogICAgICAgICAgICAgRmxleGlibGVDb250ZXh0cywKICAgICAgICAgICAgIFVuZGVjaWRhYmxlSW5zdGFuY2VzLAogICAgICAgICAgICAgU2NvcGVkVHlwZVZhcmlhYmxlcywKICAgICAgICAgICAgIE92ZXJsYXBwaW5nSW5zdGFuY2VzLAogICAgICAgICAgICAgR0FEVHMgIy19CgppbXBvcnQgUHJlbHVkZSBoaWRpbmcgKHN1Y2MpCgpkYXRhIE51bGwKZGF0YSBTdWNjIGEKCnR5cGUgT25lID0gU3VjYyBOdWxsCnR5cGUgVHdvID0gU3VjYyBPbmUKdHlwZSBUaHJlZSA9IFN1Y2MgVHdvCgpuZXd0eXBlIFNhZmVMaXN0IGwgYSA9IFNhZmVMaXN0IFthXQoKbmlsIDo6IFNhZmVMaXN0IE51bGwgYQpuaWwgPSBTYWZlTGlzdCBbXQpjb25zIDo6IGEgLT4gU2FmZUxpc3QgbiBhIC0+IFNhZmVMaXN0IChTdWNjIG4pIGEKY29ucyBhIChTYWZlTGlzdCB4KSA9IFNhZmVMaXN0ICQgYTp4CgphdCA6OiAoTGVzcyBpIG4pID0+IFNhZmVMaXN0IG4gYSAtPiBMZXNzVGhhblQgaSBJbnQgLT4gYQphdCAoU2FmZUxpc3QgYSkgPSAoYSEhKSAuIHVucGFjawoKLS0gYSA8IGIKY2xhc3MgTGVzcyBhIGIgd2hlcmUKaW5zdGFuY2UgTGVzcyBOdWxsIChTdWNjIGEpCmluc3RhbmNlIChMZXNzIGEgYikgPT4gTGVzcyAoU3VjYyBhKSAoU3VjYyBiKQoKbmV3dHlwZSBMZXNzVGhhblQgYSBiID0gTGVzc1RoYW4gYiBkZXJpdmluZyAoU2hvdykKaW5zdGFuY2UgTGVzcyAoTGVzc1RoYW5UIGEgYikgYQp1bnBhY2sgKExlc3NUaGFuIHgpID0geAoKY2xhc3MgUGx1cyBhIGIgYyB8IGEgYiAtPiBjIHdoZXJlCmluc3RhbmNlIChOdW0gYSkgPT4gUGx1cyBOdWxsIGEgYQppbnN0YW5jZSBQbHVzIGEgTnVsbCBhCmluc3RhbmNlIChQbHVzIGEgYiBjKSA9PiBQbHVzIChTdWNjIGEpIChTdWNjIGIpIGMKCmNsYXNzIFRvTGVzcyBhIGIgd2hlcmUKICBsZXNzIDo6IGEgLT4gTWF5YmUgKExlc3NUaGFuVCBiIGEpCgotLSBTaGlmdGluZyB2YWx1ZXMgdG8gdGhlIHR5cGUgbGV2ZWwgaXNuJ3QgZmFzdCB5ZXQgcG9zc2libGUKaW5zdGFuY2UgKE51bSBhLCBFcSBhKSA9PiBUb0xlc3MgYSBPbmUgd2hlcmUKICBsZXNzIDAgPSBKdXN0IChMZXNzVGhhbiAwKQogIGxlc3MgXyA9IE5vdGhpbmcKCmluc3RhbmNlIChOdW0gYSwgRXEgYSwgVG9MZXNzIGEgYikgPT4gVG9MZXNzIGEgKFN1Y2MgYikgd2hlcmUKICBsZXNzIG4gPSBjYXNlIChsZXNzICQgbiAtIDEpIDo6IE1heWJlIChMZXNzVGhhblQgYiBhKSBvZgogICAgICAgICAgICAgTm90aGluZyAtPiBOb3RoaW5nCiAgICAgICAgICAgICBKdXN0IF8gIC0+IEp1c3QgKExlc3NUaGFuIG4pCiAKc3VjYyA6OiAoTnVtIHgpID0+IExlc3NUaGFuVCBhIHggLT4gTGVzc1RoYW5UIChTdWNjIGEpIHgKc3VjYyAoTGVzc1RoYW4gbikgPSBMZXNzVGhhbiAkIG4gKyAxCgpnZXRBdCcgOjogKGknIH4gU3VjYyBpLCBMZXNzIGknIG4pID0+IFNhZmVMaXN0IG4gYSAtPiBMZXNzVGhhblQgaSBJbnQgLT4gYQpnZXRBdCcgYSBpID0gYXQgYSAkIHN1Y2MgaQoKbWFpbiA9IGRvCiAgbSA8LSByZWFkTG4gOjogSU8gSW50CiAgbiA8LSByZWFkTG4gOjogSU8gSW50CiAgcHJpbnQgJCBmb2xkbCBjb25zIG5pbCBbMS4ubl0KICAgIA==
compilation info
[1 of 1] Compiling Main ( prog.hs, prog.o )
prog.hs:65:17:
Couldn't match type `Succ n0' with `Null'
Expected type: SafeList Null a0
-> SafeList n0 (SafeList Null a0) -> SafeList Null a0
Actual type: SafeList Null a0
-> SafeList n0 (SafeList Null a0)
-> SafeList (Succ n0) (SafeList Null a0)
In the first argument of `foldl', namely `cons'
In the second argument of `($)', namely `foldl cons nil [1 .. n]'
In a stmt of a 'do' block: print $ foldl cons nil [1 .. n]
prog.hs:65:30:
Couldn't match expected type `SafeList n0 (SafeList Null a0)'
with actual type `Int'
In the expression: n
In the third argument of `foldl', namely `[1 .. n]'
In the second argument of `($)', namely `foldl cons nil [1 .. n]'
stdout