fork(1) download
  1. {-# LANGUAGE FunctionalDependencies,
  2.   MultiParamTypeClasses,
  3.   FlexibleInstances,
  4.   FlexibleContexts,
  5.   UndecidableInstances,
  6.   ScopedTypeVariables,
  7.   OverlappingInstances,
  8.   GADTs #-}
  9.  
  10. import Prelude hiding (succ)
  11.  
  12. data Null
  13. data Succ a
  14.  
  15. type One = Succ Null
  16. type Two = Succ One
  17. type Three = Succ Two
  18.  
  19. newtype SafeList l a = SafeList [a]
  20.  
  21. nil :: SafeList Null a
  22. nil = SafeList []
  23. cons :: a -> SafeList n a -> SafeList (Succ n) a
  24. cons a (SafeList x) = SafeList $ a:x
  25.  
  26. at :: (Less i n) => SafeList n a -> LessThanT i Int -> a
  27. at (SafeList a) = (a!!) . unpack
  28.  
  29. -- a < b
  30. class Less a b where
  31. instance Less Null (Succ a)
  32. instance (Less a b) => Less (Succ a) (Succ b)
  33.  
  34. newtype LessThanT a b = LessThan b deriving (Show)
  35. instance Less (LessThanT a b) a
  36. unpack (LessThan x) = x
  37.  
  38. class Plus a b c | a b -> c where
  39. instance (Num a) => Plus Null a a
  40. instance Plus a Null a
  41. instance (Plus a b c) => Plus (Succ a) (Succ b) c
  42.  
  43. class ToLess a b where
  44. less :: a -> Maybe (LessThanT b a)
  45.  
  46. -- Shifting values to the type level isn't fast yet possible
  47. instance (Num a, Eq a) => ToLess a One where
  48. less 0 = Just (LessThan 0)
  49. less _ = Nothing
  50.  
  51. instance (Num a, Eq a, ToLess a b) => ToLess a (Succ b) where
  52. less n = case (less $ n - 1) :: Maybe (LessThanT b a) of
  53. Nothing -> Nothing
  54. Just _ -> Just (LessThan n)
  55.  
  56. succ :: (Num x) => LessThanT a x -> LessThanT (Succ a) x
  57. succ (LessThan n) = LessThan $ n + 1
  58.  
  59. getAt' :: (i' ~ Succ i, Less i' n) => SafeList n a -> LessThanT i Int -> a
  60. getAt' a i = at a $ succ i
  61.  
  62. main = do
  63. m <- readLn :: IO Int
  64. n <- readLn :: IO Int
  65. print $ foldl cons nil [1..n]
  66.  
Compilation error #stdin compilation error #stdout 0s 4588KB
stdin
Standard input is empty
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
Standard output is empty