Reputation: 91
I have been trying to do a function that returns to me the first (or all it might work to but I do prefer just the first), element of a list of lists that is single, i mean:
[[x;y;z];[a;b;c];[a];[b]]
In this case I would like to get returned the a
or [a]
but I cant I tried to do a function something like:
let rec find_unit ll =
match ll with
| [x] -> [x]
and so on...
But every time I try something like this, I get in a recursion that never stops, or the function simple dont return the element. Can someone tell me how to do it properly? I still cant understand a lot of OCaml syntax... Just like in the example I dont know that to put in the line of |[x] -> [x]
, particularly the first [x]
.
Sorry for the question but I am destroying my code now and I cant find a solution.
Upvotes: 0
Views: 1414
Reputation: 91
Well all answers here helped me find a way to get the solution, and I am going to put it here because it might help someone else. I used the function:
let is_single xs = function
| [_] -> true
| _ -> false
to do: let teste xs = List.filter(fun inner ->(is_single inner)inner)xs;;
This teste
function is returning to me a List of Lists with all single elements, so to get only one element inside of that lists i did: List.hd(List.hd teste xs)
Upvotes: 0
Reputation: 15404
Try decomposing your problem into smaller subproblems.
(1) Your problem overall looks like an instance of the more general 'find'-problem, which has already been solved. See the standard function List.find
or (if you want to find them all... List.find_all
. Both functions need a predicate to pick the right element(s) from the list.
(2) You need a way to determine if some list is a singleton. It's easy, use pattern-mathing.
let is_singleton xs = function
| [_] -> true
| _ -> false
(3) Now, combine the above and you'll get a solution.
Upvotes: 3
Reputation: 66803
A couple of observations on the code you give:
Your pattern needs to match the whole string ll
, but the pattern you give seems to be intended to match just one element of ll
. A pattern more like [x] :: rest
is going to work better.
The way to avoid infinite recursion is always the same. First, make sure you check for the smallest possible input (the basis). For your problem this will be the case when ll
is an empty list. Second, if you haven't found what you're looking for, continue the search on a smaller problem. In your case this will mean searching the tail of your list.
You also need to decide what to do when there is no element of the list like the one you're looking for. If you return [x]
when you find it, you could return []
(say) if you don't find it. Or you could raise an exception like Not_found
.
(As a side comment, lists and arrays are different things in OCaml. I removed the array
tag, as your question seems to be about lists.)
Upvotes: 0