Puzzle: All 10 digits in a sum

The Puzzle: A 3 digit number is added to another 3 digit number giving a sum. The sum is a 4 digit number.
All the 10 digits are unique, that is, we use all digits from 0 to 9.
Find the smallest such numbers.
This puzzle comes from here.

The starting point to this puzzle is very similar to our last puzzle.

let digits (i:int) = 
  i.ToString().ToCharArray() |> Array.map (fun c -> (int) c - (int)'0')

let uniqueDigits (arr:'a[]) = 
   let mutable result = true
   let last = arr.Length - 1
   for i = 0 to (last - 1) do
     for j = i+1 to last do
       if arr.[i] = arr.[j] then result <- false
   result

let candidates = seq { 123 .. 987 }

We start with helper utilities to check if all the digits in a number are unique.
All the possible three-digit numbers are candidates for the two numbers we are adding.

let uniqueDigits1 num = digits num |> uniqueDigits 
let uniqueDigits2 fst snd = 
  let fst, snd = digits fst, digits snd
  Array.append fst snd |> uniqueDigits 

let uniqueDigits3 fst snd thd = 
  let fst, snd, thd = digits fst, digits snd, digits thd
  Array.append fst snd |> Array.append thd |> uniqueDigits 


let numCand =   candidates |> Seq.filter uniqueDigits1
               
let search() = seq {
    for fst in numCand do
    for snd in numCand do
      let res = fst + snd
      if res > 1000 && uniqueDigits3 fst snd res 
         then yield (fst, snd, res)
    }

let ans = search() |> Seq.head 

Functions uniqueDigits1, uniqueDigits2 and uniqueDigits3 tell us whether the provided one, two and three arguments all have unique digits amongst them. We put the digits from the argument numbers into one big array and check if all elements of the array are unique.
Once that is done, it is pretty easy to get all the answers in search(). Since the numbers in numCand are sorted, the first result in the sequence is the smallest answer.