Reputation: 95
I have a simple question!
How do I append values to a list in a loop?
below is my current code
open Scanf
open Printf
let id x = x
let const x = fun _ -> x
let read_line file = fscanf file "%s@\n" id
let is_eof file = try fscanf file "%0c" (const false) with End_of_file -> true
let _ =
let file = open_in "text.txt" in
while not (is_eof file) do
let s = read_line file in
printf "%s\n" s
done;
close_in file
I would like to append s
to an array.
Upvotes: 1
Views: 1649
Reputation: 66793
You say "list" in one place and "array" in another. In OCaml these are different things.
I suspect you're thinking of appending to a list as you would in an imperative language. But OCaml lists are immutable, i.e., you can't change a list one you've created it. So you can't append to a list in the imperative language sense.
I'll assume you're trying to learn idiomatic OCaml, i.e., you want to use its functional qualities. You could use the imperative parts of OCaml to imitate the style of coding from imperative languages, but this (IMHO) misses the real benefits of coding functionally.
In a functional language what you do instead of appending to a list is make a new list that has the contents you want. So instead of modifying a single list, making it longer and longer, you generally work with a series of lists, each longer than the last.
Beyond this, however, it's not a good idea to extend a list by adding to the end. It takes O(n) time to reach the end of a list, so repeatedly appending to a list takes O(n^2) time (for n the final length, say). You want to figure out a way to work by adding elements to the front of the list (which is fast).
You can put this all together by writing a recursive function (rather than using a while
, which generally makes sense only for imperative operations). Here's an example function that returns just the elements of a list that are odd:
let rec filter_odd l =
if l = [] then
[]
else
let (hd, tl) = (List.hd l, List.tl l) in
if hd mod 2 = 1 then hd :: filter_odd tl
else filter_odd tl
This is not idiomatic OCaml because it uses List.hd
and List.tl
rather than pattern matching. But I figure you should worry about one thing at a time :-)
(My point is that testing l = []
is like testing for EOF of the list, and List.hd l
is like reading the next input line. So this code is kind of an analogy for what you want to do.)
After pattern matching, you would want to think about tail recursion. My code isn't tail recursive, so it will consume a lot of stack space for long inputs.
I hope this helps.
Upvotes: 3