Are these two definitions identical or different - recursion

Looking at the following definitions:
let rec extractOdds list = ​
match list with ​
| [] -> []​
| x::xs -> ​
if x%2=0 then extractOdds xs else x::extractOdds xs​
and
let rec extractOdds list = ​
match list with ​
| [] -> []​
| x::xs -> ​
let rest = extractOdds xs​
if x%2=0 then rest else x::rest​
I was wondering if the two are identical. Since, the first definition uses the recursive call straight away. Whereas, the second one creates a let binding to extractOdds xs and uses it in the if expression.
Please guide me if the two are implemented identically or differently.

There is a very small difference between the two that has no effect in practice:
The first version evaluates the condition x%2=0 before evaluating extractOdds xs
The second version calls extractOdds xs before evaluating the condition x%2=0
The order will be preserved in the compiled code (which might be a bit longer for the first version), so the two versions are slightly different, but this is not observable in any way - the two calls are free of side-effects and the call to extractOdds xs happens regardless of whether x%2=0 is true or false.
This might be more obvious if you rewrite the first version using a let binding too:
let rec extractOdds list = ​
match list with ​
| [] -> []​
| x::xs -> ​
if x%2=0 then
let rest = extractOdds xs
rest
else
let rest = extractOdds xs​
x::rest
Now you can clearly see that the order of the condition and let binding is the only difference from:
let rec extractOdds list = ​
match list with ​
| [] -> []​
| x::xs -> ​
let rest = extractOdds xs​
if x%2=0 then
rest
else
x::rest
EDIT: A tail-recursive version can be written using the "accumulator" parameter. This way, you collect the elements in the wrong order, so you need to reverse the resulting list before returning it:
let rec extractOdds acc list = ​
match list with ​
| [] -> List.rev acc
| x::xs -> ​
extractOdds (if x%2=0 then acc else x::acc) xs​

Related

Tree to ordered list with tail recursion

I am actually sitting over a hour on a problem and don´t find a solution for it.
I have this data type:
type 'a tree = Empty | Node of 'a * 'a tree * 'a tree
And i have to find a function which converts a given tree in a ordered list. There is also no invariant like that the left child has to be less then the right. I already found a "normal" recursion solution but not a tail recursive solution. I already thought about to build a unordered list and sort it with List.sort, but this uses a merge sort which is not tail recursive. Maybe someone has a good advice.
Thank you!
If you want to traverse the tree in order and return a list, that means our function inorder must have the type 'a tree -> 'a list.
let rec inorder t =
match t with
| Empty -> []
| Node (v, l, r) -> List.append (inorder l) (v :: (inorder r)) (* ! *)
However List.append is in tail position, not inorder. Another problem is we have two calls to inorder. If we put inorder l in tail position, inorder r could not possibly be in tail position - and vice versa.
A neat way to work around this problem is continuation passing style. We take our function above and convert it into a helper function with an extra parameter for our continuation, return
(* convert to helper function, add an extra parameter *)
let rec loop t return =
match t with
| Empty -> ...
| Node (v, l, r) -> ...
The continuation represents "what to do next", so instead of sending values directly out of our function, we must hand them to the continuation instead. That means for the Empty case, we'll return [] - instead of simply []
let rec loop t return =
match t with
| Empty -> return []
| Node (v, l, r) -> ...
For the Node (v, l, r) case, now that we have an extra parameter we can write our own continuation that informs loop what to do next. So to construct our sorted list, we will need to loop l, then loop r (or vice versa), then we can append them. We'll write our program just like this.
let rec loop t return =
match t with
| Empty -> return []
| Node (v, l, r) ->
loop l ... (* build the left_result *)
loop r ... (* build the right_result *)
return (List.append left_result (v :: right_result))
In this next step, we'll fill in the actual lambda syntax for the continuations.
let rec loop t return =
match t with
| Empty -> return []
| Node (v, l, r) ->
loop l (fun left ->
loop r (fun right ->
return (List.append left (v :: right))))
Last, we define inorder which is a call to loop with the default continuation, identity.
let identity x =
x
let inorder t =
let rec loop t return =
match t with
| Empty -> return []
| Node (v, l, r) ->
loop r (fun right ->
loop l (fun left ->
return (List.append left (v :: right))))
in
loop t identity
As you can see loop r (fun right -> ...) is in tail position for the Node branch. loop l (fun left -> ...) is in tail position of the first continuation. And List.append ... is in tail position of the second continuation. Provided List.append is a tail-recursive procedure, inorder will not grow the stack.
Note using List.append could be a costly choice for big trees. Our function calls it once per Node. Can you think of a way to avoid it? This exercise is left for the reader.

expression has type 'a list -> 'b list but an expression was expected of type 'b list

This is my function
let rec helper inputList = function
| [] -> []
| a :: b :: hd ->
if a = b then helper ([b::hd])
else a :: helper (b::hd)
It's not complete, however I can't see why I keep getting the error in the title at helper ([b::hd]). I've tried helper (b::hd) or helper (b::hd::[]) however all come up with errors. How do I make it so that it works?
When you use function you are supplying a pattern for the parameter of the function. But you already have a parameter named inputList. So this function helper is expecting two parameters (but it ignores the first).
You can fix this by removing inputList.
You also have a problem in your first recursive call to helper. Your expression [b :: hd] is a list of lists. I suspect that you want something more like just b :: hd here.
There is at least one other problem, but I hope this helps get you started.
There are multiple errors here. One is that the keyword function means we have an implicit parameter over which we are working. So the pattern matching happens on that "invisible" parameter. But here you defined probably the explicit one: inputList. So we can remove that one:
let rec helper = function
| [] -> []
| a :: b :: hd -> if a = b then helper ([b::hd]) else a :: helper (b:: hd)
Next there is a problem with the types: in the recursion, you use:
helper ([b::hd]); and
a :: helper (b:: hd)
But you put these on the same line, and that makes no sense, since the first one passes a list of lists of elements, and the second a list of elements. So the result of the first one would be a list of list of elements, and the second one a list of elements. It does not make sense to merge these.
If I understood correctly that you want to ensure that no two consecutive elements should occur that are equal, then we should rewrite it to:
let rec helper = function
| [] -> []
| a :: b :: hd -> if a = b then helper (b::hd) else a :: helper (b:: hd)
You have defined two patterns here:
one for the empty list; and
one for a list with at least two elements.
The second one will perform recursion on the tail of the list b :: hd. So that means that eventually when we pass it a list with n elements, it will recursively work on a list with n-1 elements, n-2 elements, etc. But eventually it will have one element. And there is no case for that. So we need to add a case for the one element pattern:
let rec helper = function
| [] -> []
| h :: [] -> h :: []
| a :: b :: hd -> if a = b then helper (b::hd) else a :: helper (b:: hd)

Why doesn't my F# map implementation compile

I've started learning F# and I'd like to write my own map function using tail-recursion. Here is what I have
let my_map ff list =
let rec mapAcc ff_inner list_inner acc =
match list_inner with
| [] -> acc
| front::rest -> mapAcc( ff_inner rest (ff_inner(front) :: acc) ) //error
mapAcc ff list []
It would be called like this:
let list = my_map (fun x -> x * 2) [1;2;3;4;5] // expect [2;4;6;8;10]
I get an compilation error message on the second condition that says Type mismatch. Expecting a 'a but given a 'b list -> 'a -> 'a The resulting type would be infinite when unifying ''a' and ''b list -> 'a -> 'a'
I don't know what this error message means. I'm not sure how this can be infinite if I am passing the rest in the recursive call to mapAcc.
Note: I realize I'm rebuilding the list backwards. I'm ignoring that for now.
Just remove the parenthesis when the function calls itself:
let my_map ff list =
let rec mapAcc ff_inner list_inner acc =
match list_inner with
| [] -> acc
| front::rest -> mapAcc ff_inner rest (ff_inner(front) :: acc)
mapAcc ff list []
otherwise everything contained there is interpreted as a single parameter and ff_inner as a function call with the rest as parameters.

Erlang: choosing unique items from a list, using recursion

Given any list in Erlang, e.g.:
L = [foo, bar, foo, buzz, foo].
How can I only show the unique items of that list, using a recursive function?
I do not want to use an built-in function, like one of the lists functions (if it exists).
In my example, where I want to get to would be a new list, such as
SL = [bar, buzz].
My guess is that I would first sort the list, using a quick sort function, before applying a filter?
Any suggestions would be helpful. The example is a variation of an exercise in chapter 3 of Cesarini's & Thompson's excellent "Erlang Programming" book.
I propose this one:
unique(L) ->
unique([],L).
unique(R,[]) -> R;
unique(R,[H|T]) ->
case member_remove(H,T,[],true) of
{false,Nt} -> unique(R,Nt);
{true,Nt} -> unique([H|R],Nt)
end.
member_remove(_,[],Res,Bool) -> {Bool,Res};
member_remove(H,[H|T],Res,_) -> member_remove(H,T,Res,false);
member_remove(H,[V|T],Res,Bool) -> member_remove(H,T,[V|Res],Bool).
The member_remove function returns in one pass the remaining tail without all occurrences of the element being checked for duplicate and the test result.
I may do it this way :)
get_unique(L) ->
SortedL = lists:sort(L),
get_unique(SortedL, []).
get_unique([H | T], [H | Acc]) ->
get_unique(T, [{dup, H} | Acc]);
get_unique([H | T], [{dup, H} | Acc]) ->
get_unique(T, [{dup, H} | Acc]);
get_unique([H | T], [{dup, _} | Acc]) ->
get_unique(T, [H | Acc]);
get_unique([H | T], Acc) ->
get_unique(T, [H | Acc]);
get_unique([], [{dup, _} | Acc]) ->
Acc;
get_unique([], Acc) ->
Acc.
I think idea might be: check if you already seen the head of list. If so, skip it and recursively check the tail. If not - add current head to results, to 'seen' and recursively check the tail. Most appropriate structure for checking if you already have seen the item is set.
So,i'd propose following:
remove_duplicates(L) -> remove_duplicates(L,[], sets:new()).
remove_duplicates([],Result,_) -> Result;
remove_duplicates([Head|Tail],Result, Seen) ->
case sets:is_element(Head,Seen) of
true -> remove_duplicates(Tail,Result,Seen);
false -> remove_duplicates(Tail,[Head|Result], sets:add_element(Head,Seen))
end.
Use two accumulators. One to keep elements you have seen so far, one to hold the actual result. If you see the item for the first time (not in Seen list) prepend the item to both lists and recurse. If you have seen the item before, remove it from your result list (Acc) before recursing.
-module(test).
-export([uniques/1]).
uniques(L) ->
uniques(L, [], []).
uniques([], _, Acc) ->
lists:reverse(Acc);
uniques([X | Rest], Seen, Acc) ->
case lists:member(X, Seen) of
true -> uniques(Rest, Seen, lists:delete(X, Acc));
false -> uniques(Rest, [X | Seen], [X | Acc])
end.
unique(List) ->
Set = sets:from_list(List),
sets:to_list(Set).
This solution only filters out duplicates from a list. probably requires building upon to make it do what you want.
remove_duplicates(List)->
lists:reverse(removing(List,[])).
removing([],This) -> This;
removing([A|Tail],Acc) ->
removing(delete_all(A,Tail),[A|Acc]).
delete_all(Item, [Item | Rest_of_list]) ->
delete_all(Item, Rest_of_list);
delete_all(Item, [Another_item| Rest_of_list]) ->
[Another_item | delete_all(Item, Rest_of_list)];
delete_all(_, []) -> [].
EDIT
Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation. All rights reserved.
C:\Windows\System32>erl
Eshell V5.9 (abort with ^G)
1> List = [1,2,3,4,a,b,e,r,a,b,v,3,2,1,g,{red,green},d,2,5,6,1,4,6,5,{red,green}].
[1,2,3,4,a,b,e,r,a,b,v,3,2,1,g,
{red,green},
d,2,5,6,1,4,6,5,
{red,green}]
2> remove_duplicates(List).
[1,2,3,4,a,b,e,r,v,g,{red,green},d,5,6]
3>
Try the following code
-module(util).
-export([unique_list/1]).
unique_list([]) -> [];
unique_list(L) -> unique_list(L, []).
% Base Case
unique_list([], Acc) ->
lists:reverse(Acc);
% Recursive Part
unique_list([H|T], Acc) ->
case lists:any(fun(X) -> X == H end, T) of
true ->
unique_list(lists:delete(H,T), Acc);
false ->
unique_list(T, [H|Acc])
end.
unique(L) -> sets:to_list(sets:from_list(L)).
The simplest way would be to use a function with an "accumulator" that keeps track of what elements you already have.
So you'd write a function like
% unique_acc(Accumulator, List_to_take_from).
You can still have a clean function, by not exporting the accumulator version, and instead exporting its caller:
-module(uniqueness).
-export([unique/1]).
unique(List) ->
unique_acc([], List).
If the list to take from is empty, you're done:
unique_acc(Accumulator, []) ->
Accumulator;
And if it's not:
unique_acc(Accumulator, [X|Xs]) ->
case lists:member(X, Accumulator) of
true -> unique_acc(Accumulator, Xs);
false -> unique_acc([X|Accumulator], Xs)
end.
2 things to note:
-- This does use a list BIF -- lists:member/2. You can easily write this yourself, though.
-- The order of the elements are reversed, from original list to result. If you don't like this, you can define unique/1 as lists:reverse(unique_acc([], List)). Or even better, write a reverse function yourself! (It's easy).

OCaml nested patterns - exception despite defining pattern

I have a function defined like this:
let test_func lis =
match lis with h::t ->
match h with h2::t2 ->
h2
| [] ->
[]
| [] ->
[];;
When compiled, I get a warning that this function does not match the pattern [] - even though I defined it as the second case! I have found that I can fix this by surrounding the second match statement with parens:
let test_func lis =
match lis with h::t ->
(match h with h2::t2 ->
h2
| [] ->
[])
| [] ->
[];;
but I was wondering why this is necessary. In addition, swapping the first and second case in the top level match statement also works:
let test_func lis =
match lis with [] ->
[]
| h::t ->
match h with h2::t2 ->
h2
| [] ->
[];;
Thanks!
If we fix the indentation of your code, it looks like this:
let test_func lis =
match lis with h::t ->
match h with h2::t2 ->
h2
| [] ->
[]
| [] ->
[];;
If you look at that, it becomes obvious that there's no difference between the first and the second | [] -> []. So the compiler has no way of knowing that you intended the second one to belong to the outer match-statement and not to the inner one. Thus you need to parentheses to tell the compiler that the inner match statement should end after the first | [] -> [].
In your second version the first | [] -> [] clearly belongs to the outer match-statement because the inner match-statement doesn't even appear until farther down in the program. So there's no ambiguity and thus no need for parentheses.

Resources