F# define search function - recursion

I am new to F# and am having trouble with my code. Its a simple problem to define a function, search, with that take a boolean function and a list and return an index. So for example:
> search (fun x -> x > 10) [ 2; 12; 3; 23; 62; 8; 2 ];;
val it : int = 1
> search (fun s -> s < "horse") [ "pig"; "lion"; "horse"; "cow"; "turkey" ];;
val it : int = 3
What I have as of right now finds the right match but what I cant figure out is how to return a number instead of the rest of the list. I know I'm getting the list instead of a value back because I wrote "if f head then list". What I don't know is what I should put there instead or if what I have is not going to get the result I want.
Below is the code I have written.
let rec search f list =
match list with
| [] -> [-1]
| head::tail ->
if f head then list
else search f tail

Returning a number is easy, you just... return it. Your problem is that you don't have a number to return, because you can't derive it directly from the current state. You have to keep track of the number yourself, using some internal state variable.
When using recursion you change state by calling your function recursively with "modified" arguments. You're already doing that with the list here. To keep internal state in a recursive function you have to introduce another argument, but not expose it outside. You can solve that by using an internal recursive helper function. Here's one that keeps track of the previous item and returns that when it encounters a match:
let search f list =
let rec loop list prev =
match list with
| [] -> None
| head::tail ->
if f head then prev
else loop tail (Some head)
in
loop list None
That's a silly example, but I don't want to just solve your homework for you, because then you wouldn't learn anything. Using this you should be able to figure out how to keep a counter of which position the current item is in, and return that when it matches. Good luck!

You typically define an inner recursive function to help you carry state as you loop, and then call the inner function with an initial state.
let search predicate list =
let rec loop list index =
match list with
| [] -> -1
| head::tail ->
if predicate head then index
else loop tail (index + 1)
loop list 0

Related

Handle recursive function within an other function ocaml

If I have one or more recursive functions inside an Ocaml function how can I call them without exit from the main function taking their value as return of the main function?
I'm new in Ocaml so I'll try to explain me better...
If I have :
let function =
let rec recursive1 = ...
...
let rec recursive2 = ...
...
How can I call them inside function to tell it "Hey, do you see this recursive function? Now call it and takes its value."
Because my problem is that Ocaml as return of my functions sees Unit instead of the right return.
I will post the code below :
let change k v list_ =
let rec support k v list_ =
match list_ with
| [] -> []
| (i,value) :: tl -> if i = k
then (k,v) :: tl
else (i,value) :: support k v tl in
let inserted = support k v list_ in inserted
let () =
let k = [ (1,"ciao");(2,"Hola");(3,"Salut") ] in
change 2 "Aufwidersen" k
Change takes as input a key, a value and a (int * string )list and should return the same list of the input but changing the value linked to the key selected ( if in list ).
support, instead, makes the dirty job. It builds a new list and when k is found i = k it changes value and attach the tile, closing the function.
The return of change is unit when it should be (int * string) list. I think because inserted isn't taken as return of the function.
change does not return unit. The error in fact tells you exactly the opposite, that it returns (int * string) list but that it expects unit. And it expects unit because you're assigning it to a () pattern.
I don't know what you actually intend to do with the return value, as right now you don't seem to care about it, but you can fix the error by just assigning it to a name:
let result: (int * string) list =
let k = [ (1,"ciao");(2,"Hola");(3,"Salut") ] in
change 2 "Aufwidersen" k
Since it's not used I've added a type annotation to make sure we're getting what we expect here, as otherwise result could be anything and the compiler wouldn't complain. You don't typically need this if you're going to use result however, as you'd then get an error if the type doesn't unify with its usage.

Ocaml: Equivalence of two lists

New to Ocaml and have been working on a problem I haven't seen answered yet.
I'm working on a function where there is a tuple of 2 lists that are checked for equivalence.
Example:
# equivalence ([1;2],[1;2]);;
- : bool = true
# equivalence ([1;2],[2;1]);;
- : bool = true
# equivalence ([1;2],[1]);;
- : bool = false
Code I have:
let rec equivalent(a,b) = match a, b with
| [], [] -> true
| [], _
| _, [] -> false
| c::cc, d::dd -> if c = d then equivalent(cc,dd) else false;;
I know the problem lies with the last line. I can get a result of true if all elements are in the same order, but out of order it is a result of false. I'm having trouble going through one list to see if the other list has the element. I've tried to use List.nth, .hd, and .tl (not allowed to use .map or .itr) and have also tried to avoid the imperative features of Ocaml. Any suggestions or somewhere I should look? Thanks.
I assume this is some homework where you have to treat lists as poor mans set.
As Bergi mentioned performance wise the best would be to first sort both list and then compare them with your existing code. But that is probably not how you are supposed to solve this.
Assuming the lists are mend to be sets with not duplicate entries then equivalence of a and b means that a contains every element of b and b contains every element of a.
Start by writing a function contains: 'a -> 'a list -> bool that checks if an item is in a list. Next a function contains_all: 'a list -> 'a list -> bool that uses contains to check if every item in the first list is in the second. That then gives you
let equivalence a b = (contains_all a b) && (contains_all b a)
If your lists can contains duplicates then go with sorting the lists first. Anything else is just too impractical.
Note: contains exists as List.mem if you are allowed to use that.

Accessing the first elements in a list of Lists [F#]

I'm currently interested in F# as it is different to everything I have used before. I need to access the first element of each list contained within a large list.
If I assume that the main list contains 'x' amount of lists that themselves contain 5 elements, what would be the easiest way to access each of the first elements.
let listOfLists = [ [1;2;3;4;5]; [6;7;8;9;10]; [11;12;13;14;15] ]
My desired output would be a new list containing [1;6;11]
Currently I have
let rec firstElements list =
match list with
| list[head::tail] ->
match head with
| [head::tail] -> 1st # head then firstElements tail
To then expand on that, how would I then get all of the second elements? Would it be best to create new lists without the first elements (by removing them using a similar function) and then reusing this same function?
You can use map to extract the head element of each child list:
let firstElements li =
match li with [] -> None | h::_ -> Some h
let myfirstElements = List.map firstElements listOfLists
I'm using Ocaml's speak with little lookup on F# so this may be inaccurate, but the idea applies.
EDIT: You can also use List.head which makes it more concise and will return a int list instead of int option list. However, it throws an exception if you hits an empty list. Most of the time, I'd avoid using List.head or List.tail in this case.
The easisest way to access the first element in a list is List.head. As you have a list of lists, you just need to List.map this function:
let listOfLists = [ [1;2;3;4;5]; [6;7;8;9;10]; [11;12;13;14;15] ]
listOfLists
|> List.map List.head
//val it : int list = [1; 6; 11]
Now if you need to access other elements, you can use List.item or just index into your list with xs.[1]. But please keep in mind, that for large lists this will be inefficient and if you want fast look up use an array.
listOfLists
|> List.map (List.item 1)
//val it : int list = [2; 7; 12]
With indexing:
listOfLists
|> List.map (fun x -> x.[1])

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)

OCaml - Traversing a list without recursion

I'm trying to write following code without recursion:
let rec traverse lst =
match lst with
| a::b::t ->
(* Something that return None*)
traverse (b::t)
| _ -> ()
How to do it in imperative way ?
In an imperative way:
let traverse li =
let state = ref li in
while !state <> [] do
let x = List.hd !state in
state := List.tl !state;
(* do whatever you want *)
done
If you need to access the second element of the list, just use the appropriate List.hd call. But you may need to check that the list isn't empty first.
I see no reason to do that this way, which is heavier, less efficient and less flexible than a recursive loop.

Resources