Stack overflows and recursive sequence expressions F# - recursion

I have a sequence expression like so:
let fibSeq =
let rec fibSeq' a b =
seq { yield a
yield! fibSeq' b (a + b) }
fibSeq' 1 1
Now even for large numbers, this will not generate a stack overflow. I'm wondering why, it seems to me that to generate n Fibonacci numbers with this sequence expression each recursive call would need to return back to the caller eventually to "fold" itself into the sequence. Is there some sort of optimization going on behind the scenes here?

Yes, it's called "Tail Call Optimization"
See here: http://blogs.msdn.com/b/chrsmith/archive/2008/08/07/understanding-tail-recursion.aspx
Also Seq is lazy so its 500th member will not be evaluated until you will not have to access it in your program like:
let elm = Seq.nth 500 fibSeq

Related

Count the occurrence of an element in a list- OCaml

How would I go about counting the occurrence of a particular element in a list in Ocaml?
count 2 [1;2;2;2;2;3;4;5] # should return 4
I am having trouble figuring out how fold works and how I would apply it here. I tried doing:
count element list = fold (fun f ele head -> if ele = head then 1 else 0) 0 list
But this keeps returning 0 for my tests?
Your code is quite close. Forgive me, but I'll assume you're something of a beginner in OCaml.
In the expression fun f ele head -> ..., you're defining a function with three parameters named f, ele, and head. I suspect that you intended the f as a name for the function. But lambdas (function expressions) in OCaml don't have names (as they do in, say, JavaScript).
There is no standard function fold in OCaml. Let's assume you're working with a left fold, List.fold_left. The function to be folded takes two parameters: the first is the accumulated result from previous calls of the function, and the second is the new element from the list.
So your internal function should look more like this:
fun accum ele -> ....
The folded function returns the new accumulated result. So obviously you don't want to return just 0 or 1. You want to return the new count.
I don't want to say more, as I suspect this is part of a school assignment. I hope this helps.
(As a side comment, this question isn't about recursion. The recursion is handled for you by List.fold_left, you just need to fill in the function and initial value.)

Recursive Sequences in F#

Let's say I want to calculate the factorial of an integer. A simple approach to this in F# would be:
let rec fact (n: bigint) =
match n with
| x when x = 0I -> 1I
| _ -> n * fact (n-1I)
But, if my program needs dynamic programming, how could I sustain functional programming whilst using memoization?
One idea I had for this was making a sequence of lazy elements, but I ran into a problem. Assume that the follow code was acceptable in F# (it is not):
let rec facts =
seq {
yield 1I
for i in 1I..900I do
yield lazy (i * (facts |> Seq.item ((i-1I) |> int)))
}
Is there anything similar to this idea in F#?
(Note: I understand that I could use a .NET Dictionary but isn't invoking the ".Add()" method imperative style?)
Also, Is there any way I could generalize this with a function? For example, could I create a sequence of length of the collatz function defined by the function:
let rec collatz n i =
if n = 0 || n = 1 then (i+1)
elif n % 2 = 0 then collatz (n/2) (i+1)
else collatz (3*n+1) (i+1)
If you want to do it lazily, this is a nice approach:
let factorials =
Seq.initInfinite (fun n -> bigint n + 1I)
|> Seq.scan ((*)) 1I
|> Seq.cache
The Seq.cache means you won't repeatedly evaluate elements you've already enumerated.
You can then take a particular number of factorials using e.g. Seq.take n, or get a particular factorial using Seq.item n.
At first, i don't see in your example what you mean with "dynamic programming".
Using memorization doesn't mean something is not "functional" or breaks immutability. The important
point is not how something is implemented. The important thing is how it behaves. A function that uses
a mutable memoization is still considered pure, as long as it behaves like a pure function/immutable
function. So using a mutable variables in a limited scope that is not visible to the caller is still
considered pure. If the implementation would be important we could also consider tail-recursion as
not pure, as the compiler transform it into a loop with mutable variables under the hood. There
also exists some List.xyz function that use mutation and transform things into a mutable variable
just because of speed. Those function are still considered pure/immutable because they still behave like
pure function.
A sequence itself is already lazy. It already computes all its elements only when you ask for those elements.
So it doesn't make much sense to me to create a sequence that returns lazy elements.
If you want to speed up the computation there exists multiple ways how to do it. Even in the recursion
version you could use an accumulator that is passed to the next function call. Instead of doing deep
recursion.
let fact n =
let rec loop acc x =
if x = n
then acc * x
else loop (acc*x) (x+1I)
loop 1I 1I
That overall is the same as
let fact' n =
let mutable acc = 1I
let mutable x = 1I
while x <= n do
acc <- acc * x
x <- x + 1I
acc
As long you are learning functional programming it is a good idea to get accustomed to the first version and learn
to understand how looping and recursion relate to each other. But besides learning there isn't a reason why you
always should force yourself to always write the first version. In the end you should use what you consider more
readable and easier to understand. Not whether something uses a mutable variable as an implementation or not.
In the end nobody really cares for the exact implementation. We should view functions as black-boxes. So as long as
a function behaves like a pure function, everything is fine.
The above uses an accumulator, so you don't need to repetitive call a function again to get a value. So you also
don't need an internal mutable cache. if you really have a slow recursive version and want to speed it up with
caching you can use something like that.
let fact x =
let rec fact x =
match x with
| x when x = 1I -> 1I
| x -> (fact (x-1I)) * x
let cache = System.Collections.Generic.Dictionary<bigint,bigint>()
match cache.TryGetValue x with
| false,_ ->
let value = fact x
cache.Add(x,value)
value
| true,value ->
value
But that would probably be slower as the versions with an accumulator. If you want to cache calls to fact even across multiple
fact calls across your whole application then you need an external cache. You could create a Dictionary outside of fact and use a
private variable for this. But you also then can use a function with a closure, and make the whole process itself generic.
let memoize (f:'a -> 'b) =
let cache = System.Collections.Generic.Dictionary<'a,'b>()
fun x ->
match cache.TryGetValue x with
| false,_ ->
let value = f x
cache.Add(x,value)
value
| true,value ->
value
let rec fact x =
match x with
| x when x = 1I -> 1I
| x -> (fact (x-1I)) * x
So now you can use something like that.
let fact = memoize fact
printfn "%A" (fact 100I)
printfn "%A" (fact 100I)
and create a memoized function out of every other function that takes 1 parameter
Note that memoization doesn't automatically speed up everything. If you use the memoize function on fact
nothing get speeded up, it will even be slower as without the memoization. You can add a printfn "Cache Hit"
to the | true,value -> branch inside the memoize function. Calling fact 100I twice in a row will only
yield a single "Cache Hit" line.
The problem is how the algorithm works. It starts from 100I and it goes down to 0I. So calculating 100I ask
the cache of 99I, it doesn't exists, so it tries to calculate 98I and ask the cache. That also doesn't exists
so it goes down to 1I. It always asked the cache, never found a result and calculates the needed value.
So you never get a "Cache Hit" and you have the additional work of asking the cache. To really benefit from the
cache you need to change fact itself, so it starts from 1I up to 100I. The current version even throws StackOverflow
for big inputs, even with the memoize function.
Only the second call benefits from the cache, That is why calling fact 100I twice will ever only print "Cache Hit" once.
This is just an example that is easy to get the behaviour wrong with caching/memoization. In general you should try to
write a function so it is tail-recursive and uses accumulators instead. Don't try to write functions that expects
memoization to work properly.
I would pick a solution with an accumulator. If you profiled your application and you found that this is still to slow
and you have a bottleneck in your application and caching fact would help, then you also can just cache the results of
facts directly. Something like this. You could use dict or a Map for this.
let factCache = [1I..100I] |> List.map (fun x -> x,fact x) |> dict
let factCache = [1I..100I] |> List.map (fun x -> x,fact x) |> Map.ofList

Function calling for each element in a list

Using only recursion (ie. no loops of any sort), given a list of elements, how can I call a function each time for every element of the list using that element as an argument each time in OCaml? Fold and map would not work because although they are applying a function to each element, it returns a list of whatever function I called on each element, which is not what I want.
To better illustrate what I'm essentially trying to do in OCaml, here's the idea of what I want in Ruby code:
arr.each {|x| some_function x}
but I must do this using only recursion and no iter functions
The correct recursive function is described as:
if the list is empty, do nothing;
else, process the first element and then the tail of the list.
The corresponding code is:
let rec do_all f lst =
match lst with
| [] -> ()
| x :: xs -> f x; do_all f xs
A fairly general template for a recursive function would be this:
let rec f x =
if x is trival to handle then
handle x
else
let (part, rest) = division of x into smaller parts in
let part_result = handle_part part in
let recursive_result = f rest in
combine part_result recursive_result
Since you don't need a result, you can skip a lot of this.
Which parts of this template seem most difficult to do for your problem?
Update
(As #EduardoLeĆ³n points out, when working with lists you can test for a trivial list and break down the list into smaller parts using pattern matching. Pattern matching is cool.)
Update 2
My question is sincere. Which part are you having trouble with? Otherwise we don't know what to suggest.

Why did I still get stackoverflow even if I used tail-recursion in OCaml?

I wrote a function which generates a list of randomized ints in OCaml.
let create_shuffled_int_list n =
Random.self_init;
let rec create n' acc =
if n' = 0 then acc
else
create (n'-1) (acc # [Random.int (n/2)])
in
create n [];;
When I tried to generate 10000 integers, it gives Exception: RangeError: Maximum call stack size exceeded. error.
However, I believed in the function, I have used tail-recursion and it should not give stackoverflow error, right?
Any idea?
From the core library documentation
val append : 'a list -> 'a list -> 'a list
Catenate two lists. Same function as the infix operator #. Not tail-recursive (length of the first argument). The # operator is not tail-recursive either.
So it's not your function that's causing the overflow, it's the # function. Seeing as you only care about producing a shuffled list, however, there's no reason to be appending things onto the end of lists. Even if the # operator were tail-recursive, list append is still O(n). List prepending, however, is O(1). So if you stick your new random numbers on the front of your list, you avoid the overflow (and make your function much much faster):
let create_shuffled_int_list n =
Random.self_init;
let rec create n' acc =
if n' = 0 then acc
else
create (n'-1) (Random.int (n/2) :: acc)
in
create n [];;
If you care about the order (not sure why), then just stick a List.rev on the end:
List.rev (create n []);;
As an aside, you should not call Random.self_init in a function, since:
the user of your function may want to control the seed in order to obtain reproductible results (testing, sharing results...)
this may reset the seed with a not so random entropy source and you probably want to do this only once.

Using fold in SML

I'm trying to learn smlnj at the moment and am having trouble with a fold function.
What I'm trying to do is write a function, select, that uses the folding pattern and takes in a function and a list. It will take the head of the list into the function to determine whether it will add that element to the list. Here is an example of what I mean.
select (fn x => x mod 2 = 0) [1,2,3,4,5,6,7,8,9,10];
val it = [2,4,6,8,10] : int list
So, here is what I have so far...
fun select f l = foldl (fn (x,y) => if (f(x)) then x else 0) 0 l;
This obviously doesn't work correctly. It simply returns 10. I'm sure I need to use op:: somehow to get this to work, but I can't figure it out. My thought is that it should look something like this...
fun select f l = foldl (fn (x,y) => if (f(x)) then op:: else []) [] l;
But this does not work. Any help would be appreciated. Thanks!
You're close. The only problems are the if/else cases in the function you're passing to fold.
Remember, in your fn (x,y), x is the list element you're considering, and y is the result of folding the rest of the list. If f(x) fails, then you want to exclude x from the result, so you just pass y along. If f(x) succeeds, you want to include x in your result, so you return y#[x].
Note that it's best to avoid using the append operator (y#[x]) where you can, as it's a linear-time operation, while prepending (x::y) is constant. Of course, substituting one for the other in this case will construct your list backwards. You can get around this by folding backwards as well, i.e. using foldr instead of foldl.
What you're implementing already exists. It's called filter.
- List.filter (fn x => x mod 2 = 0) [1,2,3,4,5,6,7,8,9,10];
val it = [2,4,6,8,10] : int list
Your attempt in your second code sample is pretty close. There are several issues I might point out:
op:: is an operator, which is a function. You probably don't want to return a function. Instead, you probably want to use the operator to create a list from a head element and the rest of the list, like this: x :: y
In the else case, you are currently returning an empty list, and throwing away whatever was accumulated in y. You probably don't want to do that.
Think about whether left-fold or right-fold would be most suitable for your output

Resources