Trying to understand F # class definition syntax

Now I come to the F # classes, learning about the most important features of this language. Well, the syntax for defining a class is not easy to understand, but some of the basic concepts are now clear to me, but others are not.

1) The first thing I would like to know is just CORRECT / NOT CORRECT. I realized that classes can be defined in two ways:

  • Implicit classes. These classes have only one constructor, and in the first lines of the class you must define, using the let binding, all the internal variables that assign them a value.
  • Explicit classes. These classes have many constructors. They take the required values โ€‹โ€‹val, uninitialized values. These values โ€‹โ€‹MUST BE INITIALIZED in the constructors. If the constructor cannot determine the value for at least one of the private variables defined using the val binding, the compiler goes crazy.

SEARCH CORRECTLY ???

2) I have a problem with understanding the syntax for the constructor in explicit classes. Consider the following:

Here is the first version:

(* COMPILES :) *) type MyType = val myval: int val myother: int (* Constructor *) new (a: int, b: int) = { myval = a; myother = b; } 

Here is the second version:

 (* COMPILES :) *) type MyType = val myval: int val myother: int (* Constructor *) new (a: int, b: int) = { myval = a (* No semicolon *) myother = b (* No semicolon *) } 

Here is the latest version:

 (* DOES NOT COMPILE :( *) type MyType = val myval: int val myother: int (* Constructor *) new (a: int, b: int) = myval = a (* Using the normal indent syntax, without {} *) myother = b (* Using the normal indent syntax, without {} *) 

I donโ€™t understand why the first two versions are compiled, and the third, using the usual indentation syntax, does not. This problem only occurs in constructors, because on elements I can use indentation syntax

 (* COMPILES :) *) type MyType = val myval: int val myother: int (* Constructor *) new (a: int, b: int) = { myval = a (* No semicolon *) myother = b (* No semicolon *) } (* Indentation accepted, no {} to be inserted *) member self.mymember = let myvar = myval myvar + 10 

Why do we need a new function (constructor) {} brackets ????? I donโ€™t like it, because it seems that the sequence counts. In addition, my code also compiles when in {} missiles, between one instruction and another, a semicolon is not inserted. WHY????

+6
syntax constructor f #
source share
2 answers

As for 2), the constructor body does not look like the body of a typical function - it has a limited syntactic form, and inside the { } section it can contain only a call to the parent constructor and assignment of fields (similar to building records). When defining a normal member, you cannot wrap individual expressions in { } , even if you want to (that is, brackets are not optional in this context, they are forbidden).

+2
source share

You wrote (my attention):

Implicit classes. These classes have only one constructor , and in the first lines of the class you must define, using the let binding, all the internal variables that assign them a value.

This is actually not the case โ€” you can use implicit syntax to define a class with multiple constructors. In fact, I think it's a good idea to use the syntax of an implicit class almost always (because it simplifies declarations). Implicit classes have one primary constructor, which is the one you get implicitly - this constructor should take the largest number of parameters (but can be private):

 type Foo(a:int, b:int) = do printfn "hello" // additional constructor code member x.Multiple = a * b // some members new(x:int) = Foo(x, x) // additional constructor 

To make the constructor private, you can write

 type Foo private (a:int, b:int) = ... 

Then you can use the main constructor in the same way as a good way to initialize all fields.

+3
source share

All Articles