packages feed

liquidhaskell-0.8.2.0: docs/slides/BOS14/hs/start/04_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 a <p :: List a -> Prop>
      = N | C { x  :: a
              , xs :: List <p> a <<p>>
              }
  @-}

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

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

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

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

{-@ measure cons  :: (List a) -> Prop
    cons (C x xs) = true 
    cons (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"

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











-------------------------------------------------------------------------
-- | BOILERPLATE from before ...
-------------------------------------------------------------------------

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






















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