cnd
cnd

Reputation: 33794

How to create record with some local private functions in F#

type SQLConn =
    val mutable private connection  : string option

    member this.Connection
        with get() : string   = this.connection.Value
        and  set(v)           = this.connection           <- Some v

    new (connection : string) = {connection = Some connection;}
    new() = SQLConn @"Data Source=D:\Projects\AL\Service\ncFlow\dbase\dbflow.db3; Version=3;Password=432432434324"

I want to use "let x = 5+5" there or something like that, so how can I use private functions in my type (class) (record) , I know that I can use them if I do SQLConn() , but then I can't use val, I want to use both : val and let ...

thank you

Upvotes: 1

Views: 423

Answers (3)

Tomas Petricek
Tomas Petricek

Reputation: 243096

As Tim explains, you can only use local let bindings with the implicit constructor syntax. I would definitely follow this approach as it makes F# code more readable.

Do you have any particular reason why you also want to use val in your code? You can still use them with the implicit constructor syntax, but they have to be mutable and initialized using mutation:

type SQLConn(connection:string) as x = 
  let mutable connection = connection

  // Declare field using 'val' declaration (has to be mutable)
  [<DefaultValue>]
  val mutable a : int 

  // Initialize the value imperatively in constructor
  do x.a <- 10

  member this.Connection 
    with get() = connection and set(v) = connection <- v 

  new() = SQLConn @"Data Source=.." 

As far as I can tell val is only needed to create fields that are not private (which may be required by some code-gen based tools like ASP.NET, but is otherwise not really useful).

Upvotes: 2

pblasucci
pblasucci

Reputation: 1778

What about the following?

type SQLConn(conn:string) =
  // could put some other let bindings here... 
  // ex: 'let y = 5 + 5' or whatever
  let mutable conn = conn
  new() = SQLConn(@"some default string")
  member __.Connection 
    with get () = conn and set v = conn <- v

Upvotes: 1

Tim Robinson
Tim Robinson

Reputation: 54774

The error message explains the problem:

error FS0963: 'let' and 'do' bindings are not permitted in class definitions unless an implicit construction sequence is used. You can use an implicit construction sequence by modifying the type declaration to include arguments, e.g. 'type X(args) = ...'.

The error message is suggesting that you declare your class as type SQLConn(connection) =. If you do this, you probably ought to remove the member this.Connection property, since you'll no longer have a mutable field.

A more likely workaround would be to declare x as val x : int, then put the x = 5 + 5; initializer inside your constructor.

Upvotes: 2

Related Questions