fork download
  1. {-# LANGUAGE GADTs, TypeInType, RankNTypes, TypeOperators, TypeFamilies, TypeApplications, AllowAmbiguousTypes #-}
  2. {-# LANGUAGE ScopedTypeVariables #-}
  3.  
  4. import Data.Type.Equality
  5. import Data.Functor.Compose
  6.  
  7. -- A natural number type (that can be promoted to the type level)
  8. data Nat = Z | S Nat
  9.  
  10. -- A List of length 'n' holding values of type 'a'
  11. data List a n where
  12. Nil :: List a Z
  13. Cons :: a -> List a m -> List a (S m)
  14.  
  15. type family (+) (a :: Nat) (b :: Nat) :: Nat where
  16. Z + n = n
  17. S m + n = S (m + n)
  18.  
  19. foldlVec :: forall p a m.
  20. (forall n. a -> p n -> p (S n)) ->
  21. p Z ->
  22. List a m -> p m
  23. foldlVec pS pZ Nil = pZ
  24. foldlVec pS pZ (Cons x xs) = getCompose $ foldlVec pSS pSZ xs
  25. where
  26. pSS :: forall n. a -> Compose p S n -> Compose p S (S n)
  27. pSS = \x -> Compose . pS x . getCompose
  28. pSZ = Compose $ pS x pZ
  29.  
  30. newtype Aux a m n = Aux { getAux :: (a, List a (n + S m)) }
  31.  
  32. aux :: Ord a => List a n -> a -> List a m -> List a (n + S m)
  33. aux xs prev acc = snd . getAux $ foldlVec step init xs where
  34. init = Aux (prev, Cons prev acc)
  35. step hd (Aux (prev', acc')) = Aux (hd, Cons (max hd prev') acc')
  36.  
  37. main = return ()
Success #stdin #stdout 0s 8388607KB
stdin
Standard input is empty
stdout
Standard output is empty