user34537
user34537

Reputation:

How would i write this in F# or another functional language

I know in F# you declare variables when you assign them. I'm sure you can declare vars in a C way but how might i write this

long id=0
using (SQLiteDataReader r = command.ExecuteReader())
{
    while (r.Read())
    {
        id = r.GetInt64(0);
        //...
        break;
    }
}
//use id in sqlite now that it isnt locked

Upvotes: 0

Views: 256

Answers (3)

Tomas Petricek
Tomas Petricek

Reputation: 243126

First of all, I'm not sure if you need any looping in your example at all. Your code always returns the value from the first row. I'll complicate the example a little bit and assume that you may not want to get certain IDs as the result (so you may need to do some looping).

The usual way for writing looping constructs in functional languages is to use recursion (in many cases, you can avoid using recursion explicitly, because there are many useful higher-order functions that you can use directly). In this case, you can write a simple recursive function read that calls r.Read() once - if it succeeds then it returns the ID, if not, it calls itself recursively to read the next line:

let id = 
  ( use r = command.ExecuteReader() 
    let rec read() =
      if r.Read() then 
        let id = r.GetInt64(0)
        if weWantThisId id then id  // this is the ID we want
        else read()                 // continue reading IDs
      else 0                        // default value / throw
    read() )

The read function is written as a local function in a scope that initializes the id value. This means that when F# assigns value to id, it will run ExecuteReader and then run the local function read (this is a way to write the initialization as a single expression). Of course it may be more readable to write a fetchId function as Jon suggests (in F#, you'll again use recursion):

let fetchId() =
  use r = command.ExecuteReader() 
  let rec read() =
    if r.Read() then 
      let id = r.GetInt64(0)
      if weWantThisId id then id
      else read()
    else 0
  read()

Upvotes: 8

Brian
Brian

Reputation: 118925

Rough translation:

let mutable id = 0L 
(
    use r = command.ExecuteReader()
    let mutable finished = false
    while not(finished) do
        if r.Read() then
            id <- r.GetInt64(0)
            // ...
            finished <- true
        else
            finished <- true
)
// ...

Upvotes: 3

Jon Skeet
Jon Skeet

Reputation: 1503459

Ideally, you'd write a separate function and return the value from that function. So in C#:

long id = FetchId();

...

int FetchId(...)
{
    using (SQLiteDataReader r = command.ExecuteReader())
    {
        if (r.Read())
        {
            return r.GetInt64(0);
        }
    }
    // Work out what you want to do if there were no results...
    // Throw an exception? Change it to a nullable int and return null?   
}

Upvotes: 2

Related Questions