|
| 1 | +--- |
| 2 | +title: Never-Ending Sequences |
| 3 | +number: "100" |
| 4 | +difficulty: beginner |
| 5 | +tags: [ "seq" ] |
| 6 | +--- |
| 7 | + |
| 8 | +# Solution |
| 9 | + |
| 10 | +```ocaml |
| 11 | +type 'a cons = Cons of 'a * 'a stream |
| 12 | +and 'a stream = unit -> 'a cons |
| 13 | +
|
| 14 | +let hd (seq : 'a stream) = let (Cons (x, _)) = seq () in x |
| 15 | +let tl (seq : 'a stream) = let (Cons (_, seq)) = seq () in seq |
| 16 | +let rec take n seq = if n = 0 then [] else let (Cons (x, seq)) = seq () in x :: take (n - 1) seq |
| 17 | +let rec unfold f x () = let (y, x) = f x in Cons (y, unfold f x) |
| 18 | +let bang x = unfold (fun x -> (x, x)) x |
| 19 | +let ints x = unfold (fun x -> (x, x + 1)) x |
| 20 | +let rec map f seq () = let (Cons (x, seq)) = seq () in Cons (f x, map f seq) |
| 21 | +let rec filter p seq () = let (Cons (x, seq)) = seq () in let seq = filter p seq in if p x then Cons (x, seq) else seq () |
| 22 | +let rec iter f seq = let (Cons (x, seq)) = seq () in f x; iter f seq |
| 23 | +let to_seq seq = Seq.unfold (fun seq -> Some (hd seq, tl seq)) seq |
| 24 | +let rec of_seq seq () = match seq () with |
| 25 | +| Seq.Nil -> failwith "Not a infinite sequence" |
| 26 | +| Seq.Cons (x, seq) -> Cons (x, of_seq seq) |
| 27 | +``` |
| 28 | + |
| 29 | +# Statement |
| 30 | + |
| 31 | +Lists are finite, meaning they always contain a finite number of elements. Sequences may |
| 32 | +be finite or infinite. |
| 33 | + |
| 34 | +The goal of this exercise is to define a type `'a stream` which only contains |
| 35 | +infinite sequences. Using this type, define the following functions: |
| 36 | +```ocaml |
| 37 | +val hd : 'a stream -> 'a |
| 38 | +(** Returns the first element of a stream *) |
| 39 | +val tl : 'a stream -> 'a stream |
| 40 | +(** Removes the first element of a stream *) |
| 41 | +val take : int -> 'a stream -> 'a list |
| 42 | +(** [take n seq] returns the n first values of [seq] *) |
| 43 | +val unfold : ('a -> 'b * 'a) -> 'a -> 'b stream |
| 44 | +(** Similar to Seq.unfold *) |
| 45 | +val bang : 'a -> 'a stream |
| 46 | +(** [bang x] produces an infinitely repeating sequence of [x] values. *) |
| 47 | +val ints : int -> int stream |
| 48 | +(* Similar to Seq.ints *) |
| 49 | +val map : ('a -> 'b) -> 'a stream -> 'b stream |
| 50 | +(** Similar to List.map and Seq.map *) |
| 51 | +val filter: ('a -> bool) -> 'a stream -> 'a stream |
| 52 | +(** Similar to List.filter and Seq.filter *) |
| 53 | +val iter : ('a -> unit) -> 'a stream -> 'b |
| 54 | +(** Similar to List.iter and Seq.iter *) |
| 55 | +val to_seq : 'a stream -> 'a Seq.t |
| 56 | +(** Translates an ['a stream] into an ['a Seq.t] *) |
| 57 | +val of_seq : 'a Seq.t -> 'a stream |
| 58 | +(** Translates an ['a Seq.t] into an ['a stream] |
| 59 | + @raise Failure if the input sequence is finite. *) |
| 60 | +``` |
| 61 | +**Tip:** Use `let ... =` patterns. |
0 commit comments