Jsc
Jsc

Reputation: 177

F# Recursive Functions: make list items unique

let rec isolate (l:'a list) = 
    match l with
    | [] -> []
    | x::xs ->
        if memberof(x,xs)
        then remove (x,l)
        else isolate xs

I've already created functions memberof and remove, the only problem is that when line 6 remove(x,l) executes it doesn't continue with isolate(xs) for continued search through the list.

Is there a way to say,

if x then f(x) and f(y)

?

Upvotes: 3

Views: 212

Answers (3)

Guy Coder
Guy Coder

Reputation: 24986

let isolate list =
    let rec isolateInner searchList commonlist =
        match searchList with
        | x::xs ->
            if (memberof commonlist x) then
                isolateInner xs commonlist
            else
                let commonlist = (x :: commonlist)
                isolateInner xs commonlist
        | [] -> reverse commonlist
    isolateInner list []

This is part of an answer to your larger problem.

Notice that this does not use remove. Since you have to pass over each item in the original list and list are immutable, it is better to create a new list and only add the unique items to the new list, then return the new list.

Upvotes: 1

Kote
Kote

Reputation: 2266

In addition to CaringDev's answer.
You may look at this simple solution.
It is worth note, that it's not a fastest way to do this.

let rec isolate (acc : 'a list) (l : 'a list) = 
  match l with
  | [] -> acc
  | head :: tail -> 
    if memberof (head, tail)
    then remove (head, tail) |> isolate (acc @ [head])
    else isolate (acc @ [head]) tail

let recursiveDistinct = isolate []
let uniqValues = recursiveDistinct [ 1; 1; 2; 3] //returns [1;2;3]

Upvotes: 2

CaringDev
CaringDev

Reputation: 8551

As you are using F# immutable lists, the result of remove needs to be stored somewhere:

let rec isolate (l:'a list) = 
    match l with
    | [] -> []
    | x::xs ->
        if memberof(x,xs)
        then
            let xs = remove (x,l)
            isolate xs
        else isolate xs

To answer your more general question:

let f _ = ()
let f' z = z

let x = true
let y = 42
let z = 3.141

if x then
    f y
    f' z |> ignore

The ignore is needed here because in F# there are no statements, just expressions, so you can think of if x then f' z as

if x then
    f' z
else
    ()

and thus the first branch needs to return () as well.

Upvotes: 2

Related Questions