9.1.1 adding members to F # types

Source: Internet
Author: User

9.1.1 adding members to F # types

Now, F # iterative development comes in handy. The ability to interactively debug and test code is more important in the early stages of development, and as the code becomes more complete, it is important to consider sharing the project with other developers, providing the generic operation as a member, and using point notation to invoke it.

This means that in F #, the data type is encapsulated with the operation, which is usually the last step in the development process. This can be done using members, which can be added to any F # type, and behaves like a C # method or property. Listing 9.2 shows how to add two Rect types that use member operations.

Listing 9.2 Operations as a member of the Rect type (F #)

Type Rect = [1]

{Left:float32

Top:float32

Width:float32

Height:float32}

Creates a rectangle which is Deflatedby ' Wspace ' from the | [2]

Left and right and by ' hspace ' from thetop and bottom |

Member X.deflate (wspace, hspace) = [3]

{left = X.left + wspace

Top = X.top +hspace

Width = X.width-(2.0f* wspace)

Height = X.height-(2.0f * hspace)}

Converts the rectangle torepresentation from ' system.drawing '

Member X.torectanglef () =

RectangleF (X.left, X.top, X.width,x.height)

To create an F # data type with members, the member declaration is placed after the normal F # type declaration. As you can see in this example, the indentation of a member declaration has as many spaces as the body of the type declaration. In Listing 9.2, the declaration of the normal F # record type is first [1], and then two different methods are added as members.

The member declaration begins with the keyword member followed by the member name, with the name of the value representing the current instance. For example, x.deflate indicates that to declare a method Deflate, inside the member body, the value x points to the current instance of the record, which is somewhat similar to the This keyword in C #, so consider changing this to any name you like. F # does not retain this as a keyword, so you can name the value this, which can be written in the example. Deflate), and then use the same keyword as in C # to represent the current instance. In this book, we primarily use the name X, which is used by the community of F # for brevity purposes. In addition to this and X, another name, self, is not an F # keyword.

The parameter of the first member [3] is a tuple that creates a smaller rectangle by subtracting the specified length in the horizontal and vertical two directions. To create a type with a member, F # developers typically declare the member's parameters as tuples. This can be compiled into a standard method for use in C #, and if you specify parameters without parentheses, you can use standard function techniques, such as a hash function application with members.

Another notable example is the comment in front of the member [2], which now begins with three forward slashes (/), which represent the member's document, similar to the XML comment for C #. In F #, if you prefer, you can use XML-like syntax, but if you write a non-XML literal for a plane, the annotation is automatically treated as a digest.

Now, let's look at how to use the members of the Declaration. After the code is checked, running in F # Interactive, you see the type signature of the Rect type, which includes members and types. Listing 9.3 shows how to invoke two members.

Listing 9.3 using types and members (F # Interactive)

> Let rc = {left = 0.0f; Top =0.0f | Create a Rect value

Width = 100.0f;   Height = 100.0f};; |

Val Rc:rect

> Let small = rc.       Deflate (10.0f,30.0f); [1]

Val Small:rect = {left = 10.0f; Top =30.0f

Width = 80.0f; Height = 40.0f}

> Small.       Torectanglef (); [2]

Val Rcf:rectanglef = {x=10, y=30,width=80, height=40} {...}

We first create a value of type Rect. This does not change, and we still specify a value for each property of the record type. The next command [1] invokes the Deflate member. As you can see, we used standard object-oriented point symbols, which were used when working with. NET objects. Here, the tuple is used to describe the parameter values, but if we declare the arguments without parentheses, the call can also use the F # function call syntax, that is, the arguments are separated by spaces. The last command [2] is the value of the RectangleF object that transforms the rectangle into System.Drawing. This example now looks very much like object-oriented code, but, in any sense, does not mean that we want to get rid of functional programming styles.

Attention

This code is still purely functional (as opposed to imperative), which means that although it is more like an object-oriented organization, it has no side effects. If implemented in command style, calling the Deflate method may modify the properties of the rectangle, but our implementation does not, and the Rect data type is still immutable: Once the instance is created, the attribute value cannot be changed. Therefore, instead of modifying this value, the member returns the new RECT value after the property has been modified. This is the same behavior as the original deflate function, but keep in mind that it is very important to combine the concepts of functions (such as immutability) with object-oriented concepts (here, encapsulation). Of course, this is an unfamiliar concept for imperative object-oriented programming, and it takes the same approach to look at the System.String type.

As we've already mentioned, using a member instead of a function has the advantage of being able to easily take advantage of IntelliSense to discover operations that manipulate values. In Figure 9.1, you can see that the Visual Studio editor handles the Rect type.


Figure 9.1 Prompting for a Rect type member when editing F # source code in the visual Studio IDE

Another important benefit is that types with members are naturally available in other. NET languages, such as C #. If we use the deflate member in C #, it looks like the normal method of the type, which we will see in section 9.5. In order for all members to be compatible with C #, it is always possible that members must be carefully designed. There are some tricky situations that will be attacking the discussion, such as the high-order functions of section 9.5, and the events of chapter 16th.

When we transform a function into a member in Listing 9.2, we also convert the function declared using the let binding to the member using the keyword member declaration. While this works, you must make big changes to the source code. Fortunately, we can avoid this situation by smoothing the transition from a simple F # style to a more authentic. NET style.

9.1.1 adding members to F # types

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.