Agda-2.3.2.2: test/epic/Prelude/Stream.agda
{-# OPTIONS --universe-polymorphism #-}
module Prelude.Stream where
-- open import Coinduction
-- Infinite streams.
open import Prelude.IO
open import Prelude.Nat
open import Prelude.Unit
data Level : Set where
zero : Level
suc : (i : Level) → Level
{-# BUILTIN LEVEL Level #-}
{-# BUILTIN LEVELZERO zero #-}
{-# BUILTIN LEVELSUC suc #-}
infixl 6 _⊔_
_⊔_ : Level → Level → Level
zero ⊔ j = j
suc i ⊔ zero = suc i
suc i ⊔ suc j = suc (i ⊔ j)
{-# BUILTIN LEVELMAX _⊔_ #-}
infix 1000 ♯_
postulate
∞ : ∀ {a} (A : Set a) → Set a
♯_ : ∀ {a} {A : Set a} → A → ∞ A
♭ : ∀ {a} {A : Set a} → ∞ A → A
{-# BUILTIN INFINITY ∞ #-}
{-# BUILTIN SHARP ♯_ #-}
{-# BUILTIN FLAT ♭ #-}
data Stream (A : Set) : Set where
_∷_ : (x : A) (xs : ∞ (Stream A)) → Stream A
-- A stream processor SP A B consumes elements of A and produces
-- elements of B. It can only consume a finite number of A’s before
-- producing a B.
data SP (A B : Set) : Set where
get : (f : A → SP A B) → SP A B
put : (b : B) (sp : ∞ (SP A B)) → SP A B
-- The function eat is defined by an outer corecursion into Stream B
-- and an inner recursion on SP A B.
eat : ∀ {A B} → SP A B → Stream A → Stream B
eat (get f) (a ∷ as) = eat (f a) (♭ as)
eat (put b sp) as = b ∷ ♯ eat (♭ sp) as
-- Composition of stream processors.
_∘_ : ∀ {A B C} → SP B C → SP A B → SP A C
get f₁ ∘ put x sp₂ = f₁ x ∘ ♭ sp₂
put x sp₁ ∘ sp₂ = put x (♯ (♭ sp₁ ∘ sp₂))
sp₁ ∘ get f₂ = get (λ x → sp₁ ∘ f₂ x)
ones : Stream Nat
ones = 1 ∷ (♯ ones)
twos : Stream Nat
twos = 2 ∷ (♯ twos)
printStream : Nat -> Stream Nat -> IO Unit
printStream Z _ = return unit
printStream (S steps) (n ∷ ns) =
printNat n ,,
printStream steps (♭ ns)
main : IO Unit
main = printStream 100 twos