packages feed

liquidhaskell-0.8.2.2: tests/pos/pleORM.hs

module ORM where

{- LIQUID "--no-adt" 	      @-}
{-@ LIQUID "--exact-data-con" @-}
{-@ LIQUID "--higherorder"    @-}
{-@ LIQUID "--ple"            @-}

import Prelude hiding (length, filter)

--  here is a "user" query
{-@ prop0 :: [Row] -> [{v:Row | rowLeft v == 5}] @-}
prop0 :: [Row] -> [Row]
prop0 = filterQ (Qry Eq Fst (Const 5))

{-@ prop1 :: [Int] -> [{v:Int | v == 10}] @-}
prop1 :: [Int] -> [Int]
prop1 = filterQQ (QQ 10)

{-@ prop2 :: [Int] -> [{v:Int | v == 10}] @-}
prop2 :: [Int] -> [Int]
prop2 = filterQQ (mkQQ 10)

{-@ reflect mkQQ @-}
mkQQ :: Int -> QQ
mkQQ n = QQ n

{-@ filterQ :: q:Qry -> [Row] -> [{v:Row | evalQ q v}] @-}
filterQ :: Qry -> [Row] -> [Row]
filterQ q = filter (evalQ q)

{-@ filterQQ :: q:QQ -> [Int] -> [{v:Int | evalQQ q v}] @-}
filterQQ :: QQ -> [Int] -> [Int]
filterQQ q = filter (evalQQ q)


--------------------------------------------------------------------------------
-- | DB API
--------------------------------------------------------------------------------

data Cmp = Eq | Ne
data Val = Const Int | Fst | Snd
data Qry = Qry Cmp Val Val

data QQ  = QQ Int


data Row = Row {rowLeft :: Int, rowRight :: Int}
{-@ data Row = Row {rowLeft :: Int, rowRight :: Int} @-}

{-@ reflect evalQQ @-}
evalQQ :: QQ -> Int -> Bool
evalQQ (QQ x) y = x == y

{-@ reflect evalQ @-}
evalQ :: Qry -> Row -> Bool
evalQ (Qry o v1 v2) r = evalC o (evalV v1 r) (evalV v2 r)

{-@ reflect evalV @-}
evalV :: Val -> Row -> Int
evalV (Const n) _ = n
evalV Fst       r = rowLeft  r
evalV Snd       r = rowRight r

{-@ reflect evalC @-}
evalC :: Cmp -> Int -> Int -> Bool
evalC Eq x y = x == y
evalC Ne x y = x /= y

--------------------------------------------------------------------------------
-- | Generic List API
--------------------------------------------------------------------------------

{-@ filter :: f:(a -> Bool) -> [a] -> [{v:a | f v}] @-}
filter :: (a -> Bool) -> [a] -> [a]
filter f (x:xs)
  | f x         = x : filter f xs
  | otherwise   =     filter f xs
filter _ []     = []