Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is this idiomatic F# for a fairly quick infinite recursive sequence?

Whilst solving the 12th project euler problem I set about making an infinite sequence to get successive triangular numbers. My first attempt was:

let slowTriangularNumbers =

  let rec triangularNumbersFrom n = 
    seq { 
      yield seq { 0 .. n } |> Seq.sum
      yield! triangularNumbersFrom (n + 1) 
    }

   triangularNumbersFrom 1

This turned out to be very slow - each time getting the next item it had to compute all of the additions leading up to n.

My next attempt was:

let fasterTriangularNumbers =

  let cache = System.Collections.Generic.Dictionary<int, int>()
  cache.[0] <- 0         

  let rec triangularNumbersFrom n = 
  seq { 
    cache.[n] <- cache.[n - 1] + n                   
    yield cache.[n]
    yield! triangularNumbersFrom (n + 1) 
  }

  triangularNumbersFrom 1

Introducing the mutable dictionary has speeded it up considerably, but is this normal to have a mutable collection, or is there another way I could have represented state?

like image 510
NickL Avatar asked Dec 27 '13 18:12

NickL


People also ask

How do you use idiomatic in a sentence?

He made the world of men and things his study, learned to write his mother-tongue with idiomatic conciseness, and nourished his imagination on the masterpieces of the Romans. The sounds of a computer executing these machine operations is a completely idiomatic digital sound.


1 Answers

I think this is more idiomatic:

Seq.unfold (fun (i, n) -> Some(n, (i+1, n+i))) (2, 1)

You might prefer this alternative:

seq { 2 .. System.Int32.MaxValue }
|> Seq.scan (+) 1
like image 125
J D Avatar answered Sep 30 '22 02:09

J D