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 Functor ((->) w) where fmap f = (f .) 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..]