Type Mismatch in ocaml - recursion

I am trying to recursively find the nth element in a list in ocaml using the following code.
let rec get_val x n = match x with
[] -> -1
| h::t -> if (n=0) then h else get_val t (n-1)
;;
print_int get_val [1; 2; 3] 1;;
However this code is giving me the error
This function has type int -> unit
It is applied to too many arguments; maybe you forgot a `;'.

Your definition is asking for two separate parameters (i.e., it is curried). But you're passing a pair of parameters (t, n - 1). These aren't the same thing.
To get past this problem, change the recursive call to get_val t (n - 1).
You might consider raising the Not_found exception when the list is too short. That way your code will work for lists of all types.
Update
Now the error is in the line where you test your function. You need parentheses there as well.
(You shouldn't keep changing your code. People who come to this page later won't be able to follow the questions and answers.)

Related

Calculating the Trace of a Matrix; Syntactical Errors

I was tasked with writing OCAML code to calculate the Trace of a square matrix (the values inside the diagonal of a matrix). As a bonus, and for my own understanding, I'd also like to write code to produce a list of the trace of a square matrix.
I've created a tail recursive function utilizing the List.map feature which strips the first element of each row, and so on and so forth.
let trace m =
let rec helper m acc =
match m with
|[] -> acc
|(x::_) -> helper(List.map(fun(y::ys) -> ys)) (acc+x)
in helper m 0 ;;
Unfortunately I believe my syntax is off and I am unsure how to go about solving this. I think I have the right theory/idea in mind but poor implementation. Any help would be greatly appreciated
This is the error I get when I run the code:
This expression has type 'a list list -> 'a list list but an expression was expected of type 'b list
1:Warning 8: this pattern-matching is not exhaustive.
Here is an example of a case that is not matched:
[]
As #glennsl says, you should do the work to ask a good question. You don't tell us anything about the error you see, for example. Generally you should copy/paste the error text into your question.
When I copy/paste your code I see an error for this fragment:
(List.map (fun (y :: ys) -> ys))
List.map takes two parameters: the first is a function, which you have. The second is a list to map over, which you don't have here. Since you don't supply a list, the value of this expression is a function that expects a list and returns the transformed list.
Since the first parameter of helper is a list of lists (I assume), and not a function, you have a type error. (Not a syntax error.)
Most likely you need to supply the list over which you want to map your function.

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.

How to create a Prolog predicate that removes 2nd to last element?

I need help creating a predicate that removes the 2nd to last element of a list and returns that list written in Prolog. So far I have
remove([],[]).
remove([X],[X]).
remove([X,Y],[Y]).
That is as far as I've gotten. I need to figure out a way to recursively go through the list until it is only two elements long and then reassemble the list to be returned. Help with explanation if you can.
Your definition so far is perfect! It is a little bit too specialized, so we will have to extend it. But your program is a solid foundation.
You "only" need to extend it.
remove([],[]).
remove([X],[X]).
remove([_,X],[X]).
remove([X,_,Y], [X,Y]).
remove([X,Y,_,Z], [X,Y,Z]).
remove([X,Y,Z,_,Z2], [X,Y,Z,Z2]).
...
OK, you see how to continue. Now, let us identify common cases:
...
remove([X,Y,_,Z], [X,Y,Z]).
% ^^^ ^^^
remove([X,Y,Z,_,Z2], [X,Y,Z,Z2]).
% ^^^^^ ^^^^^
...
So, we have a common list prefix. We could say:
Whenever we have a list and its removed list, we can conclude that by adding one element on both sides, we get a longer list of that kind.
remove([X|Xs], [X|Ys]) :-
remove(Xs,Ys).
Please note that the :- is really an arrow. It means: Provided what is true on the right-hand side, also what is found on the left-hand side will be true.
H-h-hold a minute! Is this really the case? How to test this? (If you test just for positive cases, you will always get a "yes".) We don't have the time to conjure up some test cases, do we? So let us let Prolog do the hard work for us! So, Prolog, fill in the blanks!
remove([],[]).
remove([X],[X]).
remove([_,X],[X]).
remove([X|Xs], [X|Ys]) :-
remove(Xs,Ys).
?- remove(Xs,Ys). % most general goal
Xs = [], Ys = []
; Xs = [A], Ys = [A]
; Xs = [_,A], Ys = [A]
; Xs = [A], Ys = [A] % redundant, but OK
; Xs = [A,B], Ys = [A,B], unexpected % WRONG
; Xs = [A,_,B], Ys = [A,B]
; Xs = [A,B], Ys = [A,B], unexpected % WRONG again!
; Xs = [A,B,C], Ys = [A,B,C], unexpected % WRONG
; Xs = [A,B,_,C], Ys = [A,B,C]
; ... .
It is tempting to reject everything and start again from scratch.
But in Prolog you can do better than that, so let's calm down to estimate the actual damage:
Some answers are incorrect. And some answers are correct.
It could be that our current definition is just a little bit too general.
To better understand the situation, I will look at the unexpected success remove([1,2],[1,2]) in detail. Who is the culprit for it?
Even the following program slice/fragment succeeds.
remove([],[]).
remove([X],[X]) :- false.
remove([_,X],[X]) :- false.
remove([X|Xs], [X|Ys]) :-
remove(Xs,Ys).
While this is a specialization of our program it reads: that remove/2 holds for all lists that are the same. That can't be true! To fix the problem we have to do something in the remaining visible part. And we have to specialize it. What is problematic here is that the recursive rule also holds for:
remove([1,2], [1,2]) :-
remove([2], [2]).
remove([2], [2]) :-
remove([], []).
That kind of conclusion must be avoided. We need to restrict the rule to those cases were the list has at least two further elements by adding another goal (=)/2.
remove([X|Xs], [Y|Ys]) :-
Xs = [_,_|_],
remove(Xs, Ys).
So what was our error? In the informal
Whenever we have a list and its removed list, ...
the term "removed list" was ambiguous. It could mean that we are referring here to the relation remove/2 (which is incorrect, because remove([],[]) holds, but still nothing is removed), or we are referring here to a list with an element removed. Such errors inevitably happen in programming since you want to keep your intuitions afresh by using a less formal language than Prolog itself.
For reference, here again (and for comparison with other definitions) is the final definition:
remove([],[]).
remove([X],[X]).
remove([_,X],[X]).
remove([X|Xs], [X|Ys]) :-
Xs = [_,_|_],
remove(Xs,Ys).
There are more efficient ways to do this, but this is the most straight-forward way.
I will try to provide another solution which is easier to construct if you only consider the meaning of "second last element", and describe each possible case explicitly:
rem_2nd_last([], []).
rem_2nd_last([First|Rest], R) :-
rem_2nd_last_2(Rest, First, R). % "Lag" the list once
rem_2nd_last_2([], First, [First]).
rem_2nd_last_2([Second|Rest], First, R) :-
rem_2nd_last_3(Rest, Second, First, R). % "Lag" the list twice
rem_2nd_last_3([], Last, _SecondLast, [Last]). % End of list: drop second last
rem_2nd_last_3([This|Rest], Prev, PrevPrev, [PrevPrev|R]) :-
rem_2nd_last_3(Rest, This, Prev, R). % Rest of list
The explanation is hiding in plain view in the definition of the three predicates.
"Lagging" is a way to reach back from the end of the list but keep the predicate always deterministic. You just grab one element and pass the rest of the list as the first argument of a helper predicate. One way, for example, to define last/2, is:
last([H|T], Last) :-
last_1(T, H, Last).
last_1([], Last, Last).
last_1([H|T], _, Last) :-
last_1(T, H, Last).

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.

Resources