Olivier
Olivier

Reputation: 5688

Seq{/* yielding sth */} : Error with mutable variables

I'm trying to learn F# (I'm a C# developper), and facing my first problem while trying to compile following code :


   let decompose n = 
       seq{
           let mutable c = n
           let mutable i = 2L
           if c%2L=0L then
               c <- c/2L
               yield 2L
           if (c=1L) then yield 1L
           else 
               while c<>1L do
                   if c % i=0L then
                       c<-c/i
                       yield i
                   else i <- i+2L
       }

I tried to google compilation error (see below), unsuccessfully (probably because it's in french) :

La variable mutable 'c' est utilisée de manière incorrecte. Impossible de capturer les variables mutables à l'aide de fermetures. Supprimez cette utilisation de la mutation ou utilisez une cellule de référence mutable allouée par tas via 'ref' et '!'.

Could someone help me fixing this ? Or at least give me the english version of the error ?

Thanks !

Upvotes: 3

Views: 230

Answers (2)

Benjol
Benjol

Reputation: 66531

Just to answer the other half of your question, the English version of that compiler message is:

The mutable variable 'c' is used in an invalid way. Mutable variables cannot be captured by closures. Consider eliminating this use of mutation or using a heap-allocated mutable reference cell via 'ref' and '!'.

Upvotes: 0

Olivier
Olivier

Reputation: 5688

Ok guys... StackOverflow is pretty well designed : I found my answer in the following post (found in the "Related" column) :

The mutable variable 'i' is used in an invalid way.?

I'm not removing my question for french people who will google this error !

BTW, here is the working code :

let decompose n = 
    seq{
        let c = ref 0L
        c := n
        let i = ref 3L
        if !c%2L=0L then
            c := !c / 2L
            yield 2L
        if (!c=1L) then yield 1L
        else 
            while !c<>1L do
                if !c % !i=0L then
                    c:= !c / !i
                    yield !i
                else i := !i+2L
    }

// returns [|3;41|]
let dec = decompose 123L |> Seq.ToArray

Upvotes: 3

Related Questions