liquidhaskell-0.6.0.0: tests/pos/BinarySearch.hs
{- | By Gabriel Gonzalez, from:
http://www.haskellforall.com/2015/12/compile-time-memory-safety-using-liquid.html
-}
module BinarySearch (binarySearch) where
import Data.Vector as Vector
binarySearch :: Ord a => a -> Vector a -> Maybe Int
binarySearch x v =
if Vector.length v == 0
then Nothing
else loop x v 0 (Vector.length v - 1)
midpoint :: Int -> Int -> Int
midpoint lo hi = (lo + hi) `div` 2
{-@
loop
:: Ord a
=> x : a
-> v : Vector a
-> lo : { lo : Int | 0 <= lo && lo < vlen v }
-> hi : { hi : Int | lo <= hi && hi < vlen v }
-> Maybe Int
/ [hi - lo]
@-}
loop :: Ord a => a -> Vector a -> Int -> Int -> Maybe Int
loop x v lo hi = do
let mid = lo + ((hi - lo) `div` 2) -- midpoint lo hi
if x < v ! mid
then do
let hi' = mid - 1
if lo <= hi'
then loop x v lo hi'
else Nothing
else if v ! mid < x
then do
let lo' = mid + 1
if lo' <= hi
then loop x v lo' hi
else Nothing
else Just mid