Definition fin_stream {A: Type} (h: list A) : stream A.
exists (fun n => nth_error h n).
intros.
rewrite nth_error_None_iff in H0 |- *.
omega.
Defined.
Definition inf_stream {A: Type} (h: nat -> A) : stream A.
exists (fun n => Some (h n)).
intros.
congruence.
Defined.
Definition empty_stream {A: Type}: stream A := fin_stream nil.
Definition empty_stream_spec {A: Type}: forall n, @empty_stream A n = None.
Program Definition stream_map {A B: Type} (f: A -> B) (h: stream A): stream B :=
fun n => match h n return option B with
| Some a => Some (f a)
| None => None
end.
Next Obligation.
pose proof proj2_sig h x y H.
change (proj1_sig h) with (stream_get h) in H1.
destruct (h x), (h y); try congruence.
specialize (H1 eq_refl); congruence.
Qed.

Lemma stream_map_spec {A B: Type}: forall (f: A -> B) (h: stream A) (n: nat),
stream_map f h n =
match h n return option B with
| Some a => Some (f a)
| None => None
end.