Suppose I've got the sequence <1,<>,2,<>>.
How could I go about deleting the empty lists and get <1,2>?
Ideally, without using recursion or iteration.
Thanks.
PS: I'm using FP programming language
What you're probably looking for is filter. It takes a predicate and takes out elements not satisfying it.
Since the FP language has a weird syntax and I couldn't find any documentation , I can't provide an implementation of filter. But in general, it can be implemented using a fold -- which is just the inserts from the link you provided.
Here's what I mean (in Haskell):
filter p list = foldr (\x xs -> if p x then x:xs else xs) [] list¹
If you don't get this, look here. When you have written filter, you can call it like
newList = filter notEmpty theList
(where nonEmpty is a predicate or lambda). Oh, and of course this only hides recursion by using another function; at some point, you have to recurse.
¹The : operator in Haskell is list consing (appending an element to the head), not function application.
Related
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.
I'm working with a polymorphic binary search tree with the standard following type definition:
type tree =
Empty
| Node of int * tree * tree (*value, left sub tree, right sub tree*);;
I want to do an in order traversal of this tree and add the values to a list, let's say. I tried this:
let rec in_order tree =
match tree with
Empty -> []
| Node(v,l,r) -> let empty = [] in in_order r#empty;
v::empty;
in_order l#empty
;;
But it keeps returning an empty list every time. I don't see why it is doing that.
When you're working with recursion you need to always reason as follows:
How do I solve the easiest version of the problem?
Supposing I have a solution to an easier problem, how can I modify it to solve a harder problem?
You've done the first part correctly, but the second part is a mess.
Part of the problem is that you've not implemented the thing you said you want to implement. You said you want to do a traversal and add the values to a list. OK, so then the method should take a list somewhere -- the list you are adding to. But it doesn't. So let's suppose it does take such a parameter and see if that helps. Such a list is traditionally called an accumulator for reasons which will become obvious.
As always, get the signature right first:
let rec in_order tree accumulator =
OK, what's the easy solution? If the tree is empty then adding the tree contents to the accumulator is simply the identity:
match tree with
| Empty -> accumulator
Now, what's the recursive case? We suppose that we have a solution to some smaller problems. For instance, we have a solution to the problem of "add everything on one side to the accumulator with the value":
| Node (value, left, right) ->
let acc_with_right = in_order right accumulator in
let acc_with_value = value :: acc_with_right in
OK, we now have the accumulator with all the elements from one side added. We can then use that to add to it all the elements from the other side:
in_order left acc_with_value
And now we can make the whole thing implement the function you tried to write in the first place:
let in_order tree =
let rec aux tree accumulator =
match tree with
| Empty -> accumulator
| Node (value, left, right) ->
let acc_with_right = aux right accumulator in
let acc_with_value = value :: acc_with_right in
aux left acc_with_value in
aux tree []
And we're done.
Does that all make sense? You have to (1) actually implement the exact thing you say you're going to implement, (2) solve the base case, and (3) assume you can solve smaller problems and combine them into solutions to larger problems. That's the pattern you use for all recursive problem solving.
I think your problem boils down to this. The # operator returns a new list that is the concatenation of two other lists. It doesn't modify the other lists. In fact, nothing ever modifies a list in OCaml. Lists are immutable.
So, this expression:
r # empty
Has no effect on the value named empty. It will remain an empty list. In fact, the value empty can never be changed either. Variables in OCaml are also immutable.
You need to imagine constructing and returning your value without modifying lists or variables.
When you figure it out, it won't involve the ; operator. What this operator does is to evaluate two expressions (to the left and right), then return the value of the expression at the right. It doesn't combine values, it performs an action and discards its result. As such, it's not useful when working with lists. (It is used for imperative constructs, like printing values.)
If you thought about using # where you're now using ;, you'd be a lot closer to a solution.
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.
As follow up to yesterday's question Erlang: choosing unique items from a list, using recursion
In Erlang, say I wanted choose all unique items from a given list, e.g.
List = [foo, bar, buzz, foo].
and I had used your code examples resulting in
NewList = [bar, buzz].
How would I further manipulate NewList in Erlang?
For example, say I not only wanted to choose all unique items from List, but also count the total number of characters of all resulting items from NewList?
In functional programming we have patterns that occur so frequently they deserve their own names and support functions. Two of the most widely used ones are map and fold (sometimes reduce). These two form basic building blocks for list manipulation, often obviating the need to write dedicated recursive functions.
Map
The map function iterates over a list in order, generating a new list where each element is the result of applying a function to the corresponding element in the original list. Here's how a typical map might be implemented:
map(Fun, [H|T]) -> % recursive case
[Fun(H)|map(Fun, T)];
map(_Fun, []) -> % base case
[].
This is a perfect introductory example to recursive functions; roughly speaking, the function clauses are either recursive cases (result in a call to iself with a smaller problem instance) or base cases (no recursive calls made).
So how do you use map? Notice that the first argument, Fun, is supposed to be a function. In Erlang, it's possible to declare anonymous functions (sometimes called lambdas) inline. For example, to square each number in a list, generating a list of squares:
map(fun(X) -> X*X end, [1,2,3]). % => [1,4,9]
This is an example of Higher-order programming.
Note that map is part of the Erlang standard library as lists:map/2.
Fold
Whereas map creates a 1:1 element mapping between one list and another, the purpose of fold is to apply some function to each element of a list while accumulating a single result, such as a sum. The right fold (it helps to think of it as "going to the right") might look like so:
foldr(Fun, Acc, [H|T]) -> % recursive case
foldr(Fun, Fun(H, Acc), T);
foldr(_Fun, Acc, []) -> % base case
Acc.
Using this function, we can sum the elements of a list:
foldr(fun(X, Sum) -> Sum + X, 0, [1,2,3,4,5]). %% => 15
Note that foldr and foldl are both part of the Erlang standard library, in the lists module.
While it may not be immediately obvious, a very large class of common list-manipulation problems can be solved using map and fold alone.
Thinking recursively
Writing recursive algorithms might seem daunting at first, but as you get used to it, it turns out to be quite natural. When encountering a problem, you should identify two things:
How can I decompose the problem into smaller instances? In order for recursion to be useful, the recursive call must take a smaller problem as its argument, or the function will never terminate.
What's the base case, i.e. the termination criterion?
As for 1), consider the problem of counting the elements of a list. How could this possibly be decomposed into smaller subproblems? Well, think of it this way: Given a non-empty list whose first element (head) is X and whose remainder (tail) is Y, its length is 1 + the length of Y. Since Y is smaller than the list [X|Y], we've successfully reduced the problem.
Continuing the list example, when do we stop? Well, eventually, the tail will be empty. We fall back to the base case, which is the definition that the length of the empty list is zero. You'll find that writing function clauses for the various cases is very much like writing definitions for a dictionary:
%% Definition:
%% The length of a list whose head is H and whose tail is T is
%% 1 + the length of T.
length([H|T]) ->
1 + length(T);
%% Definition: The length of the empty list ([]) is zero.
length([]) ->
0.
You could use a fold to recurse over the resulting list. For simplicity I turned your atoms into strings (you could do this with list_to_atom/1):
1> NewList = ["bar", "buzz"].
["bar","buzz"]
2> L = lists:foldl(fun (W, Acc) -> [{W, length(W)}|Acc] end, [], NewList).
[{"buzz",4},{"bar",3}]
This returns a proplist you can access like so:
3> proplists:get_value("buzz", L).
4
If you want to build the recursion yourself for didactic purposes instead of using lists:
count_char_in_list([], Count) ->
Count;
count_char_in_list([Head | Tail], Count) ->
count_char_in_list(Tail, Count + length(Head)). % a string is just a list of numbers
And then:
1> test:count_char_in_list(["bar", "buzz"], 0).
7
Lets say that I would like to construct a list (L2) by appending elements of another list (L) one by one. The result should be exactly the same as the input.
This task is silly, but it'll help me understand how to recurse through a list and remove certain elements.
I have put together the following code:
create(L, L2) :- (\+ (L == []) -> L=[H|T], append([H], create(T, L2), L2);[]).
calling it by
create([1,2,3,4], L2)
returns
L2 = [1|create([2,3,4], **)\.
which is not a desired result.
You say that you want to understand how prolog works so I'll not give you a full solution but a hint.
Functions in prolog do not return values, they just create bindings.
When you say
append([H], create(T, L2), L2);[]).
you are trying to use a return value.
Try to have append create bindings that you use in the recursive call.