Cannot use try / with blocks inside sequence expressions. How to get around this?

Consider that

Pentagonal numbers are generated by the formula, Pn=n(3nāˆ’1)/2.

I decided to create a sequence of pentagonal numbers in F #:

let pentagonalSeq = { 1..Int32.MaxValue } |> Seq.map (fun n -> n*(3*n-1)/2)

So far so good. For most purposes, I only want to compute a pair of small integer pentagonal numbers. But maybe I would like, for example, to get all the Int32pentagonal numbers. I thought it would be possible to simply calculate them until I get it OverflowException(I use verified arithmetic). The trouble is that F # is not very happy with his idea, shouting that

'try/with' cannot be used inside sequence expressions

What is the best way to keep this young lady satisfied?

Suppose I want to create int32_pentagonalSeqone that:

  • uses pentagonalSeq
  • It does not require any additional calculations, trying to predict whether or not the next element may overflow.

+3
3

, - , , ! , , - :

let takeWhileNonException (input:seq<_>) = seq { 
  use ps = input.GetEnumerator()
  while (try ps.MoveNext() with _ -> false) do 
    yield ps.Current }

, for loop yield! try.. with, ( ) . MoveNext ( ) false, ​​ .

, , :

pentagonalSeq
|> takeWhileNonException
|> Seq.last
+4

- , ?

let pentagonal n = 
   try
      Some(n*(3*n-1)/2)
   with
     | ex -> None

let x = { 1.. Int32.MaxValue } |> Seq.map pentagonal
+2

Seq.unfold , :

open Checked
let generator n = 
    try
        Some ((n*(3*n-1)/2), n+1)
    with 
       | :? System.OverflowException -> None

let pentagonalSeq = Seq.unfold generator 1

FSI, , :

pentagonalSeq |> Seq.last;;
val it : int = 1073731660

-, Int32, , , 2147438935. 1073731660 2147438935 int. , try-with :

let pentagonalSeq = Seq.unfold
                        (fun n -> let pentagonal = n*(3L*n-1L)/2L in
                                  if pentagonal > (int64 System.Int32.MaxValue) then
                                      None // Sequence is over
                                  else
                                      Some((int pentagonal), n+1L)) // Member and next state
                         1L  // Initial state

FSI , , int , :

pentagonalSeq |> Seq.last;;
val it : int = 2147438935
+2
source

All Articles