module Data.InfiniteSeq
( Seq
, Nat
, head
, tail
, cons
, elemAt
, drop
, toStream
, toList
) where
import Prelude hiding (head, tail, drop)
import Control.Comonad
import Data.Stream (Stream, mkStream)
type Nat = Int
type Seq a = Nat -> a
instance Comonad ((->) Nat) where
extract s = s 0
duplicate s = \i -> drop i s
head :: Seq a -> a
head s = s 0
tail :: Seq a -> Seq a
tail s = \i -> s (i + 1)
cons :: a -> Seq a -> Seq a
cons x s = \i -> if i == 0 then x else s (i 1)
elemAt :: Nat -> Seq a -> a
elemAt i s = s i
drop :: Nat -> Seq a -> Seq a
drop n s = \i -> s (i+n)
toStream :: Seq a -> Stream a
toStream s = mkStream s head tail
toList :: Seq a -> [a]
toList s = map s [0..]