Re: Page 76 of OCaml by John Whitington ???
"'Mr. Herr' [email protected] [ocaml_beginners]" <[email protected]> Fri, 25 Mar 2016 22:22:04 +0100
| Newsgroups | gmane.comp.lang.ocaml.beginners |
|---|---|
| Message-ID | <[email protected]> |
more answers below On 25.03.2016 19:44, Douglas Lewit [email protected] [ocaml_beginners] wrote: > > Well my exploration of LISP will have to wait, otherwise I'll be mediocre at many > languages rather than really good at just a few! Changing the topic a bit, I'm > really struggling with something here. If you look at the 99 Problems in Ocaml > page, there's a problem that requires you to write a pack function that basically > does this: > > pack [1; 1; 1; 1; 2; 2; 2; 2; 3; 3] ;; > > [[1; 1; 1; 1]; [2; 2; 2; 2]; [3; 3]]; > > Okay... confusion here! First off look at */rec aux current acc/* ( why can't > people just call it "accumulator" to make tracing easier?! ) it is idiomatic in OCaml to use the shortest possible names in functions, like in math. And idiomatic means easy to read (once you got the idiom that is). Here my comments on pack: let pack list = (* external view is 1 parameter, so we better hide *) (* the details of the recursion in an inner function. *) let rec aux current acc = function (* inner functions are often called aux, or loop, or f *) | [] -> [] (* empty input empty output *) | [x] -> (* one element, maybe rest of previous calls: *) (* prepend to current, and the result to acc, and return it *) (x :: current) :: acc | a :: (b :: _ as t) -> (* more than 1 element: destructure as first, second, rest *) (* with second and rest bound to t *) (* if first and second are equal prepend fist to current and loop *) if a = b then aux (a :: current) acc t (* else we know a is a sinlge element or the last of sequence of equals *) (* so we incorporate it into the current list and prepend this to acc *) (* emptying current for the next step *) else aux [] ((a :: current) :: acc) t (* which is quite tricky and optimized, current happens to always have *) (* the correct state *) in (* end of aux *) List.rev (aux [] [] list) (* this is what pack does: it calls aux with empty current, empty acc, *) (* and the original list *) ;; > One last question. With regard to recursive functions that create ref > variables.... are those ref variables reinitialized every time the function is > called? I imagine they should be and would be, but.... I don't know. I'll have to > experiment with that one and figure it out. > well this depends on what you want to do - examples please. Generally internal ref values are just mutable variables, and you have to return the value if it is of use outside. /Str.