Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

F# how to write a function which provides a counter number in serial order

Tags:

f#

So if you go to a bank there is a device from which you can pull a number out.

I want to write a function like that. So everytime this function is called we get a next number in the series.

So if this function is called first time, we get 1. second time we get 2.... so on and so forth.

this is what I have written so far

let X =
    let myseq = seq {1 .. 100}
    let GetValue = 
        Seq.head (Seq.take 1 myseq)
    GetValue;;

 let p = X;;
 p;;
 p;;
 p;;

But it always return 1. My hope was that since the sequence is a closure, everytime I do a take, I will get the next number.

I also tried this

let X =
    let mutable i = 1
    let GetValue = 
        i <- i + 1
        i
    GetValue;;

 let p = X;;
 p;;
 p;;
 p;;

This one only prints 2...

like image 573
Knows Not Much Avatar asked Aug 11 '13 04:08

Knows Not Much


People also ask

What does ⟨F⟩ mean?

This sound is usually considered to be an allophone of /h/, which is pronounced in different ways depending upon its context; Japanese /h/ is pronounced as [ɸ] before /u/. In Welsh orthography, ⟨f⟩ represents /v/ while ⟨ff⟩ represents /f/. In Slavic languages, ⟨f⟩ is used primarily in words of foreign (Greek, Latin, or Germanic) origin.

What is F# in programming?

What is F# 1 Rich data types. Data types such as Records and Discriminated Unions let you represent complex data and domains. ... 2 Enforced correctness with functions and pattern matching. F# functions are easy to declare and powerful in practice. ... 3 Functions to define operations on objects. ...

What is the origin of the letter F?

F, or f, is the sixth letter in the modern English alphabet and the ISO basic Latin alphabet. Its name in English is ef (pronounced / ˈɛf / ), plural efs. The origin of 'F' is the Semitic letter waw that represented a sound like /v/ or /w/.

What does F stand for in the Etruscan alphabet?

In the Etruscan alphabet, 'F' probably represented /w/, as in Greek, and the Etruscans formed the digraph 'FH' to represent /f/.


3 Answers

You have to return a function. And to it, you have to pass something every time, i.e. your +1 has to be deferred.

let factory = 
    let counter = ref 0
    fun () -> 
        counter.Value <- !counter + 1
        !counter

and now you get

> factory();;
val it : int = 1
> factory();;
val it : int = 2

doing it this way has the nice side-effect, that you completely hide the mutable reference cell inside the function and thus there is no way to somehow tamper with your counter.

like image 145
Daniel Fabian Avatar answered Oct 06 '22 13:10

Daniel Fabian


Just for a reference, if you wanted a version that uses sequences (just like the first approach in your question), you can do that using the IEnumerable interface:

let factory = 
  // Infinite sequence of numbers & get enumerator
  let numbers = Seq.initInfinite id
  let en = numbers.GetEnumerator()
  fun () -> 
    // Move to the next number and return it
    en.MoveNext() |> ignore
    en.Current

It behaves the same way as factory in Daniel's answer. This still uses mutable state - but it is hidden inside the enumerator (which keeps the current state of the sequence between MoveNext calls).

In this simple case, I'd use Daniel's version, but the above might be handy if you want to iterate over something else than just increasing numbers.

like image 36
Tomas Petricek Avatar answered Oct 06 '22 13:10

Tomas Petricek


You need to move the variable outside the declaration. You also need to declare a function so that it gets evaluated each time it is called.

let mutable i = 1
let X() =
    i <- i + 1
    i

This ensures that the function is called each time and that the variable is correctly incremented.

like image 6
John Palmer Avatar answered Oct 06 '22 12:10

John Palmer