{-# OPTIONS --cubical-compatible --safe --guardedness #-}
module Codata.Guarded.Stream where
open import Level hiding (suc)
open import Data.Nat.Base
open import Function.Base
open import Data.List.Base as List using (List; []; _∷_)
open import Data.Product.Base hiding (map)
open import Data.Vec.Base using (Vec; []; _∷_)
open import Data.List.NonEmpty.Base as List⁺ using (List⁺; _∷_)
open import Algebra.Core
open import Relation.Binary.PropositionalEquality.Core using (_≡_; refl)
private
variable
a b c : Level
A : Set a
B : Set b
C : Set c
infixr 5 _∷_
record Stream (A : Set a) : Set a where
coinductive
constructor _∷_
field
head : A
tail : Stream A
open Stream public
tabulate : (ℕ → A) → Stream A
tabulate f .head = f 0
tabulate f .tail = tabulate (f ∘′ suc)
repeat : A → Stream A
repeat = tabulate ∘′ const
infixr 5 _++_
_++_ : List A → Stream A → Stream A
[] ++ s = s
(x ∷ xs) ++ s = x ∷ xs ++ s
unfold : (A → A × B) → A → Stream B
unfold next seed .head = next seed .proj₂
unfold next seed .tail = unfold next (next seed .proj₁)
iterate : (A → A) → A → Stream A
iterate f = unfold < f , id >
nats : Stream ℕ
nats = tabulate id
lookup : Stream A → ℕ → A
lookup xs zero = head xs
lookup xs (suc n) = lookup (tail xs) n
infix 4 _[_]
_[_] : Stream A → ℕ → A
_[_] = lookup
map : (A → B) → Stream A → Stream B
map f s .head = f (s .head)
map f s .tail = map f (s .tail)
ap : Stream (A → B) → Stream A → Stream B
ap fs xs .head = fs .head (xs .head)
ap fs xs .tail = ap (fs .tail) (xs .tail)
scanl : (B → A → B) → B → Stream A → Stream B
scanl c n s .head = n
scanl c n s .tail = scanl c (c n (s .head)) (s .tail)
zipWith : (A → B → C) → Stream A → Stream B → Stream C
zipWith f s t .head = f (s .head) (t .head)
zipWith f s t .tail = zipWith f (s .tail) (t .tail)
transpose : List (Stream A) → Stream (List A)
transpose [] = repeat []
transpose (s ∷ ss) = zipWith _∷_ s (transpose ss)
tails : Stream A → Stream (Stream A)
tails s .head = s
tails s .tail = tails (s .tail)
evens : Stream A → Stream A
evens s .head = s .head
evens s .tail = evens (s .tail .tail)
odds : Stream A → Stream A
odds s = evens (s .tail)
infixr 5 _⁺++_
_⁺++_ : List⁺ A → Stream A → Stream A
(x ∷ xs) ⁺++ ys = x ∷ xs ++ ys
concat : Stream (List⁺ A) → Stream A
concat {A = A} = ++-concat []
module Concat where
++-concat : List A → Stream (List⁺ A) → Stream A
++-concat [] s .head = s .head .List⁺.head
++-concat [] s .tail = ++-concat (s .head .List⁺.tail) (s .tail)
++-concat (x ∷ xs) s .head = x
++-concat (x ∷ xs) s .tail = ++-concat xs s
cycle : List⁺ A → Stream A
cycle = concat ∘′ repeat
transpose⁺ : List⁺ (Stream A) → Stream (List⁺ A)
transpose⁺ (s ∷ ss) = zipWith _∷_ s (transpose ss)
splitAt : ∀ n → Stream A → Vec A n × Stream A
splitAt zero s = [] ,′ s
splitAt (suc n) s = map₁ (s .head ∷_) (splitAt n (s .tail))
take : ∀ n → Stream A → Vec A n
take = proj₁ ∘₂ splitAt
drop : ℕ → Stream A → Stream A
drop = proj₂ ∘₂ splitAt
chunksOf : ∀ n → Stream A → Stream (Vec A n)
chunksOf n s .head = take n s
chunksOf n s .tail = chunksOf n (drop n s)
interleave : Op₂ (Stream A)
interleave xs ys .head = xs .head
interleave xs ys .tail = interleave ys (xs .tail)
interleave⁺ : List⁺ (Stream A) → Stream A
interleave⁺ = concat ∘′ transpose⁺
cantor : Stream (Stream A) → Stream A
cantor s .head = s .head .head
cantor s .tail = cantor (zipWith _∷_ (s .head .tail) (s .tail))
plane : {B : A → Set b} → Stream A → (∀ a → Stream (B a)) → Stream (Σ A B)
plane xs fs = cantor (map (λ x → map (x ,_) (fs x)) xs)
_ : take 21 (plane nats (const nats))
≡ (0 , 0)
∷ (0 , 1) ∷ (1 , 0)
∷ (0 , 2) ∷ (1 , 1) ∷ (2 , 0)
∷ (0 , 3) ∷ (1 , 2) ∷ (2 , 1) ∷ (3 , 0)
∷ (0 , 4) ∷ (1 , 3) ∷ (2 , 2) ∷ (3 , 1) ∷ (4 , 0)
∷ (0 , 5) ∷ (1 , 4) ∷ (2 , 3) ∷ (3 , 2) ∷ (4 , 1) ∷ (5 , 0)
∷ []
_ = refl