Raw File
tick-append.hs
{-

data Tick t a = Tick a
type T w a = T {v|v=w} a

pure :: x -> T 0 a
pure x = Tick x

</> :: t1 t2 -> T t1 (a -> b) -> T t2 a -> T (t1 + t2) b
Tick f </> Tick x = Tick (f x)

(++) :: xs:[a] -> ys:[a] -> T (len xs) {v|v=len xs + len ys}
[] ++ ys = pure ys
(x:xs') ++ ys = pure (x:) </> (xs' ++ ys)

(<*>) as forall a, b. t1:Int ~> t2: Int ~>
         Tick {v | v = t1} (a -> b)
      -> Tick {v | v = t2} a
      -> Tick {v | v = t1 + t2} b
Tick f <*> Tick x = Tick (f x)

(>>=) as forall a, b. t1:Int ~> t2: Int ~>
         Tick {v | v = t1} a
      -> (a -> Tick {v | v = t2} b)
      -> Tick {v | v = t1 + t2} b

step as forall a. t1:Int ~>
     -> m: Int
     -> Tick {v | v = t1} a
     -> Tick {v | v = t1 + m} a
step m (Tick x) = Tick x

(</>) as forall a, b. t1:Int ~> t2:Int
      -> Tick {v | v = t1} (a -> b)
      -> Tick {v | v = t2} a
      -> Tick {v | v = t1 + t2 + 1} b
(</>) = (<*>)

(++) :: forall a.
     -> xs: [a]
     -> ys: [a]
     -> Tick {v | v = length xs} {v | v = length xs + length ys}
[] ++ ys = pure ys
(x:xs') ++ ys = pure (x:) </> (xs' ++ ys)

reverse :: xs:[a] -> Tick {v | v = ((length xs * length xs) / 2) + ((length xs + 1) / 2)} [a]
reverse [] = pure []
reverse (x:xs) = reverse xs >>= (++ [x])
-}

measure mNil :: List [>Int] -> Bool
measure mCons :: List [>Int] -> Bool
measure mLength :: List [>Int] -> Int
measure not :: Bool -> Bool

empty as x:(List >Int) -> {v: Bool | (v == mNil x) /\ (v == not (mCons x)) /\ (v == (mLength x == 0))}
empty = (0)

nil as {v: List >Int | (mNil v) /\ (mLength v = 0) /\ (not (mCons v))}
nil = (0)

cons as x:Int -> xs:(List >Int) -> {v: List >Int | (mCons v) /\ (mLength v = mLength xs + 1) /\ (not (mNil v))}
cons = (0)

first as {v: List >Int | mCons v} -> Int
first = (0)

rest as rs:{v: List >Int | mCons v} -> {v: List >Int | mLength v == mLength rs - 1 }
rest = (0)

pure as rforall a. x:a -> Tick >{v:Int | v == 0} >a
pure = (0)

ap as rforall a, b. t1:Int ~> t2:Int ~>
  (Tick >{v:Int | v == t1} >x:a -> b) ->
  Tick >{v:Int | v == t2} >a ->
  Tick >{v:Int | v == t1 + t2 + 1} >b
ap = (0)

ap0 as rforall a, b. t10:Int ~> t20:Int ~>
  (Tick >{v:Int | v == t10} >x:a -> b) ->
  Tick >{v:Int | v == t20} >a ->
  Tick >{v:Int | v == t10 + t20} >b
ap0 = (0)

append :: xs:(List >Int) -> ys:(List >Int) ->
  Tick >{v:Int | v = mLength xs} >{v: List >Int | mLength v = (mLength xs) + (mLength ys)}
append = \xs -> \ys ->
  if empty xs
    then pure ys
    else (ap (pure (\rest -> cons (first xs) rest)) (append (rest xs) ys))

mapA :: n:Int ~>
  (x:Int -> Tick >{v:Int | v == n} >Int) ->
  xs:(List >Int) ->
  Tick >{v:Int | v == n * (mLength xs)} >(List >Int)
mapA = \f xs ->
  if empty xs
    then pure nil
    else (ap0 (ap0 (pure cons) (f (first xs))) (mapA f (rest xs)))
back to top