liquidhaskell-0.7.0.0: tests/todo/splash-total.hs
{-@ LIQUID "--totality" @-}
module SplashTotal where
import Prelude hiding (foldr1, head)
head :: [a] -> a
incr :: Int -> Int
average :: [Int] -> Int
group :: (Eq a) => [a] -> [[a]]
foldr1 :: (a -> a -> a) -> [a] -> a
impossible :: String -> a
merge :: Ord a => [a] -> [a] -> [a]
fib :: Int -> Int
ups :: [Int]
insertSort :: (Ord a) => [a] -> [a]
insert :: (Ord a) => a -> [a] -> [a]
-- REPLACE `-` with `+`
{-@ incr :: Nat -> Nat @-}
incr x = x + 1
{-@ impossible :: {v: String | False} -> a @-}
impossible = error
--------------------------------------------------------------------------------
-- TOTALITY A 1
{- type NonEmpty a = {v:[a] | 0 < len v } @-}
-- replace input with NonEmpty a
{-@ type NonEmpty a = {v:[a] | 0 < len v} @-}
{-@ head :: NonEmpty a -> a @-}
head (x:_) = x
-- head [] = impossible "head on empty list"
-- TOTALITY A 2
-- replace output with NonEmpty a
-- >>> unstutter "ssslllyttthhherrrinnn"
-- "slytherin"
unstutter :: String -> String
unstutter = map head . group
{-@ group :: (Eq a) => [a] -> [[a]] @-}
group [] = []
group (x:xs) = (x:ys) : group zs
where
(ys, zs) = span (x ==) xs
--------------------------------------------------------------------------------
-- replace input with NonEmpty a
-- ADD signature: foldr1 :: (a -> a -> a) -> {v:[a] | len v > 0} -> a
{-@ foldr1 :: (a -> a -> a) -> [a] -> a @-}
foldr1 op (x:xs) = foldr op x xs
foldr1 _ _ = impossible "foldr1 on empty list"
{-@ average :: [Int] -> Int @-}
average xs = foldr1 (+) xs `div` length xs
--------------------------------------------------------------------------------
-- TERMINATION
-- ADD / [len xs + len ys]
{-@ fib :: Nat -> Nat @-}
fib 0 = 1
fib 1 = 1
fib n = fib (n-1) + fib (n-2)
-- .
{-@ merge :: Ord a => xs:[a] -> ys:[a] -> [a]
/ [ len xs + len ys] @-}
merge xs [] = xs
merge [] ys = ys
merge (x:xs) (y:ys)
| x <= y = x : merge xs (y:ys)
| otherwise = y : merge (x:xs) ys
--------------------------------------------------------------------------------
-- type OrdList a = [a]<{\x v -> x <= v}> .
-- USER DEFINED INVARIANTS
{-@ type OrdList a = [a]<{\x v -> x <= v}> @-}
{-@ ups :: OrdList Int @-}
ups = [1, 2, 3, 4, 5]
{-@ insertSort :: (Ord a) => [a] -> OrdList a @-}
insertSort = foldr insert []
{-@ insert :: (Ord a) => a -> OrdList a -> OrdList a @-}
insert x [] = [x]
insert x (y:ys)
| x <= y = x : y : ys
| otherwise = y : insert x ys
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------