Function calling for each element in a list - recursion

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.

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.)

FP language: removing empty lists from a list

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.

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

Confused over behavior of List.mapi in F#

I am building some equations in F#, and when working on my polynomial class I found some odd behavior using List.mapi
Basically, each polynomial has an array, so 3*x^2 + 5*x + 6 would be [|6, 5, 3|] in the array, so, when adding polynomials, if one array is longer than the other, then I just need to append the extra elements to the result, and that is where I ran into a problem.
Later I want to generalize it to not always use a float, but that will be after I get more working.
So, the problem is that I expected List.mapi to return a List not individual elements, but, in order to put the lists together I had to put [] around my use of mapi, and I am curious why that is the case.
This is more complicated than I expected, I thought I should be able to just tell it to make a new List starting at a certain index, but I can't find any function for that.
type Polynomial() =
let mutable coefficients:float [] = Array.empty
member self.Coefficients with get() = coefficients
static member (+) (v1:Polynomial, v2:Polynomial) =
let ret = List.map2(fun c p -> c + p) (List.ofArray v1.Coefficients) (List.ofArray v2.Coefficients)
let a = List.mapi(fun i x -> x)
match v1.Coefficients.Length - v2.Coefficients.Length with
| x when x < 0 ->
ret :: [((List.ofArray v1.Coefficients) |> a)]
| x when x > 0 ->
ret :: [((List.ofArray v2.Coefficients) |> a)]
| _ -> [ret]
I think that a straightforward implementation using lists and recursion would be simpler in this case. An alternative implementation of the Polynomial class might look roughly like this:
// The type is immutable and takes initial list as constructor argument
type Polynomial(coeffs:float list) =
// Local recursive function implementing the addition using lists
let rec add l1 l2 =
match l1, l2 with
| x::xs, y::ys -> (x+y) :: (add xs ys)
| rest, [] | [], rest -> rest
member self.Coefficients = coeffs
static member (+) (v1:Polynomial, v2:Polynomial) =
// Add lists using local function
let newList = add v1.Coefficients v2.Coefficients
// Wrap result into new polynomial
Polynomial(newList)
It is worth noting that you don't really need mutable field in the class, since the + operator creates and returns a new instance of the type, so the type is fully immutable (as you'd usually want in F#).
The nice thing in the add function is that after processing all elements that are available in both lists, you can simply return the tail of the non-empty list as the rest.
If you wanted to implement the same functionality using arrays, then it may be better to use a simple for loop (since arrays are, in principle, imperative, the usual imperative patterns are usually the best option for dealing with them). However, I don't think there is any particular reason for preferring arrays (maybe performance, but that would have to be evaluated later during the development).
As Pavel points out, :: operator appends a single element to the front of a list (see the add function above, which demonstrates that). You could write what you wanted using # which concatenates lists, or using Array.concat (which concatenates a sequence of arrays).
An implementation using higher-order functions and arrays is also possible - the best version I can come up with would look like this:
let add (a1:_[]) (a2:_[]) =
// Add parts where both arrays have elements
let l = min a1.Length a2.Length
let both = Array.map2 (+) a1.[0 .. l-1] a2.[0 .. l-1]
// Take the rest of the longer array
let rest =
if a1.Length > a2.Length
then a1.[l .. a1.Length - 1]
else a2.[l .. a2.Length - 1]
// Concatenate them
Array.concat [ both; rest ]
add [| 6; 5; 3 |] [| 7 |]
This uses slices (e.g. a.[0 .. l]) which give you a part of an array - you can use these to take the parts where both arrays have elements and the remaining part of the longer array.
I think you're misunderstanding what operator :: does. It's not used to concatenate two lists. It's used to prepend a single element to the list. Consequently, it's type is:
'a -> 'a list -> 'a list
In your case, you're giving ret as a first argument, and ret is itself a float list. Consequently, it expects the second argument to be of type float list list - hence why you need to add an extra [] to the second argument to make it to compile - and that will also be the result type of your operator +, which is probably not what you want.
You can use List.concat to concatenate two (or more) lists, but that is inefficient. In your example, I don't see the point of using lists at all - all this converting back & forth is going to be costly. For arrays, you can use Array.append, which is better.
By the way, it's not clear what is the purpose of mapi in your code at all. It's exactly the same as map, except for the index argument, but you're not using it, and your mapping is the identity function, so it's effectively a no-op. What's it about?

Using recursion an append in prolog

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.

Resources