liquidhaskell-0.8.2.0: docs/slides/BOS14/hs/end/000_Refinements.hs
{-@ LIQUID "--short-names" @-}
{-@ LIQUID "--no-warnings" @-}
{-@ LIQUID "--no-termination" @-}
module Refinements where
import Prelude hiding (map, foldr, foldr1)
divide :: Int -> Int -> Int
-----------------------------------------------------------------------
-- | 1. Simple Refinement Types
-----------------------------------------------------------------------
{-@ type Nat = {v:Int | v >= 0} @-}
{-@ type Pos = {v:Int | v > 0} @-}
{-@ type NonZero = {v:Int | v /= 0} @-}
{-@ six :: NonZero @-}
six = 10 :: Int
-----------------------------------------------------------------------
-- | 2. Function Contracts: Preconditions & Dead Code
-----------------------------------------------------------------------
{-@ dead :: {v:_ | false} -> a @-}
dead msg = error msg
-----------------------------------------------------------------------
-- | 3. Function Contracts: Safe Division
-----------------------------------------------------------------------
abs :: Int -> Int
abs x | x > 0 = x
| otherwise = 0 - x
{-@ divide :: Int -> NonZero -> Int @-}
divide x 0 = dead "divide-by-zero"
divide x n = x `div` n
avg2 x y = divide (x + y) 2
avg3 x y z = divide (x + y + z) 3
-----------------------------------------------------------------------
-- | But whats the problem here?
-----------------------------------------------------------------------
avg xs = divide total n
where
total = sum xs
n = length xs