packages feed

liquidhaskell-0.8.2.3: tests/pos/Streams.hs

module Streams where

import Prelude hiding (take, repeat)

import Language.Haskell.Liquid.Prelude

-------------------------------------------------------------------------
-- | Lists 
-------------------------------------------------------------------------
 
data List a = N | C { x :: a, xs :: List a }

-- | Associate an abstract refinement with the _tail_ xs

{-@ data List [size] a <p :: List a -> Bool>
      = N | C { x  :: a
              , xs :: List <p> a <<p>>
              }
  @-}

-------------------------------------------------------------------------
-- | Infinite Streams
-------------------------------------------------------------------------

-- | Infinite List = List where _each_ tail is a `kons` ...

{-@ type Stream a = {xs: List <{\v -> kons v}> a | kons xs} @-}

-- | A simple measure for when a `List` is a `Cons`

{-@ measure kons @-}
kons :: List a -> Bool 
kons (C x xs) = True 
kons (N)      = False 

-------------------------------------------------------------------------
-- | Creating an Infinite Stream
-------------------------------------------------------------------------

{-@ lazy repeat @-}
                 
{-@ repeat :: a -> Stream a @-}
repeat   :: a -> List a
repeat x = x `C` repeat x


-------------------------------------------------------------------------
-- | Using an Infinite Stream
-------------------------------------------------------------------------

{-@ take        :: n:Nat -> Stream a -> {v:List a | size v = n} @-}
take 0 _        = N
take n (C x xs) = x `C` take (n-1) xs
take _ N        = liquidError "never happens"

-------------------------------------------------------------------------











-- | Other specs from before ...

{-@ measure size @-}
{-@ size :: List a -> Nat @-} 
size :: List a -> Int 
size (N)      = 0
size (C x xs) = (1 + size xs)






















-----------------------------------------------------
take            :: Int -> List a -> List a