1
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

Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
cnd
  • 32,616
  • 62
  • 183
  • 313

3 Answers3

2

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.

Tim Robinson
  • 53,480
  • 10
  • 121
  • 138
2

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).

Tomas Petricek
  • 240,744
  • 19
  • 378
  • 553
  • 1
    @Tomas: val is also needed to create private fields which are available to static members and other instances of the same type: http://stackoverflow.com/questions/3098942/accessing-let-bound-fields-from-static-members/3098968#3098968 – Stephen Swensen Dec 06 '10 at 14:48
  • @Tomas: If you need good ol' structure fields without automatic properties, `val mutable` is also needed. – elmattic Dec 06 '10 at 16:01
  • An aside question, `connection` is used as a parameter and local variable name, is there a way to access both if its values from one of SQLConns methods or should it have been named `let mutable _connection = connection`? – gradbot Dec 06 '10 at 16:05
  • @Stephen: Good point - although this could be solved by using private properties, so it is not _strictly_ needed (unlike `val` in e.g. ASP.NET). @Stringer: I thought `let mutable` also creates standard field (without property). – Tomas Petricek Dec 06 '10 at 16:17
  • 1
    @gradbot: There is no way to access the original value. I used same name intentionally so that the mutable value hides the constructor parameter (and you cannot accidentally access the original value when you, in fact, wanted the value of mutable field) – Tomas Petricek Dec 06 '10 at 16:18
  • @Tomas: Actually I was speaking of `[]` types. For reference types I don't know. – elmattic Dec 06 '10 at 17:24
  • it works fine , but ... this 'as x' syntax is looking like a bit weird. – cnd Dec 07 '10 at 05:29
1

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
pblasucci
  • 1,738
  • 12
  • 16