F# – Pattern Matching ”; Previous Next Pattern matching allows you to “compare data with a logical structure or structures, decompose data into constituent parts, or extract information from data in various ways”. In other terms, it provides a more flexible and powerful way of testing data against a series of conditions and performing some computations based on the condition met. Conceptually, it is like a series of if… then statements. Syntax In high level terms, pattern matching follows this syntax in F# − match expr with | pat1 – result1 | pat2 -> result2 | pat3 when expr2 -> result3 | _ -> defaultResult Where, Each | symbol defines a condition. The -> symbol means “if the condition is true, return this value…”. The _ symbol provides the default pattern, meaning that it matches all other things like a wildcard. Example 1 The following example, calculates the Fibonacci numbers using pattern matching syntax − Live Demo let rec fib n = match n with | 0 -> 0 | 1 -> 1 | _ -> fib (n – 1) + fib (n – 2) for i = 1 to 10 do printfn “Fibonacci %d: %d” i (fib i) When you compile and execute the program, it yields the following output − Fibonacci 1: 1 Fibonacci 2: 1 Fibonacci 3: 2 Fibonacci 4: 3 Fibonacci 5: 5 Fibonacci 6: 8 Fibonacci 7: 13 Fibonacci 8: 21 Fibonacci 9: 34 Fibonacci 10: 55 You can also chain together multiple conditions, which return the same value. For example − Example 2 Live Demo let printSeason month = match month with | “December” | “January” | “February” -> printfn “Winter” | “March” | “April” -> printfn “Spring” | “May” | “June” -> printfn “Summer” | “July” | “August” -> printfn “Rainy” | “September” | “October” | “November” -> printfn “Autumn” | _ -> printfn “Season depends on month!” printSeason “February” printSeason “April” printSeason “November” printSeason “July” When you compile and execute the program, it yields the following output − Winter Spring Autumn Rainy Pattern Matching Functions F# allows you to write pattern matching functions using the function keyword − Live Demo let getRate = function | “potato” -> 10.00 | “brinjal” -> 20.50 | “cauliflower” -> 21.00 | “cabbage” -> 8.75 | “carrot” -> 15.00 | _ -> nan (* nan is a special value meaning “not a number” *) printfn “%g”(getRate “potato”) printfn “%g”(getRate “brinjal”) printfn “%g”(getRate “cauliflower”) printfn “%g”(getRate “cabbage”) printfn “%g”(getRate “carrot”) When you compile and execute the program, it yields the following output − 10 20.5 21 8.75 15 Adding Filters or Guards to Patterns You can add filters, or guards, to patterns using the when keyword. Example 1 Live Demo let sign = function | 0 -> 0 | x when x < 0 -> -1 | x when x > 0 -> 1 printfn “%d” (sign -20) printfn “%d” (sign 20) printfn “%d” (sign 0) When you compile and execute the program, it yields the following output − -1 1 0 Example 2 Live Demo let compareInt x = match x with | (var1, var2) when var1 > var2 -> printfn “%d is greater than %d” var1 var2 | (var1, var2) when var1 < var2 -> printfn “%d is less than %d” var1 var2 | (var1, var2) -> printfn “%d equals %d” var1 var2 compareInt (11,25) compareInt (72, 10) compareInt (0, 0) When you compile and execute the program, it yields the following output − 11 is less than 25 72 is greater than 10 0 equals 0 Pattern Matching with Tuples The following example demonstrates the pattern matching with tuples − Live Demo let greeting (name, subject) = match (name, subject) with | (“Zara”, _) -> “Hello, Zara” | (name, “English”) -> “Hello, ” + name + ” from the department of English” | (name, _) when subject.StartsWith(“Comp”) -> “Hello, ” + name + ” from the department of Computer Sc.” | (_, “Accounts and Finance”) -> “Welcome to the department of Accounts and Finance!” | _ -> “You are not registered into the system” printfn “%s” (greeting (“Zara”, “English”)) printfn “%s” (greeting (“Raman”, “Computer Science”)) printfn “%s” (greeting (“Ravi”, “Mathematics”)) When you compile and execute the program, it yields the following output − Hello, Zara Hello, Raman from the department of Computer Sc. You are not registered into the system Pattern Matching with Records The following example demonstrates pattern matching with records − Live Demo type Point = { x: float; y: float } let evaluatePoint (point: Point) = match point with | { x = 0.0; y = 0.0 } -> printfn “Point is at the origin.” | { x = xVal; y = 0.0 } -> printfn “Point is on the x-axis. Value is %f.” xVal | { x = 0.0; y = yVal } -> printfn “Point is on the y-axis. Value is %f.” yVal | { x = xVal; y = yVal } -> printfn “Point is at (%f, %f).” xVal yVal evaluatePoint { x = 0.0; y = 0.0 } evaluatePoint { x = 10.0; y = 0.0 } evaluatePoint { x = 0.0; y = 10.0 } evaluatePoint { x = 10.0; y = 10.0 } When you compile and execute the program, it yields the following output − Point is at the origin. Point is on the x-axis. Value is 10.000000. Point is on the y-axis. Value is 10.000000. Point is at (10.000000, 10.000000). Print Page Previous Next Advertisements ”;
Category: fsharp
F# – Enumerations
F# – Enumerations ”; Previous Next An enumeration is a set of named integer constants. In F#, enumerations, also known as enums, are integral types where labels are assigned to a subset of the values. You can use them in place of literals to make code more readable and maintainable. Declaring Enumerations The general syntax for declaring an enumeration is − type enum-name = | value1 = integer-literal1 | value2 = integer-literal2 … The following example demonstrates the use of enumerations − Example Live Demo // Declaration of an enumeration. type Days = | Sun = 0 | Mon = 1 | Tues = 2 | Wed = 3 | Thurs = 4 | Fri = 5 | Sat = 6 // Use of an enumeration. let weekend1 : Days = Days.Sat let weekend2 : Days = Days.Sun let weekDay1 : Days = Days.Mon printfn “Monday: %A” weekDay1 printfn “Saturday: %A” weekend1 printfn “Sunday: %A” weekend2 When you compile and execute the program, it yields the following output − Monday: Mon Saturday: Sat Sunday: Sun Print Page Previous Next Advertisements ”;
F# – Basic I/O
F# – Basic I/O ”; Previous Next Basic Input Output includes − Reading from and writing into console. Reading from and writing into file. Core.Printf Module We have used the printf and the printfn functions for writing into the console. In this section, we will look into the details of the Printf module of F#. Apart from the above functions, the Core.Printf module of F# has various other methods for printing and formatting using % markers as placeholders. The following table shows the methods with brief description − Value Description bprintf : StringBuilder → BuilderFormat<”T> → ”T Prints to a StringBuilder. eprintf : TextWriterFormat<”T> → ”T Prints formatted output to stderr. eprintfn : TextWriterFormat<”T> → ”T Prints formatted output to stderr, adding a newline. failwithf : StringFormat<”T,”Result> → ”T Prints to a string buffer and raises an exception with the given result. fprintf : TextWriter → TextWriterFormat<”T> → ”T Prints to a text writer. fprintfn : TextWriter → TextWriterFormat<”T> → ”T Prints to a text writer, adding a newline. kbprintf : (unit → ”Result) → StringBuilder → BuilderFormat<”T,”Result> → ”T Like bprintf, but calls the specified function to generate the result. kfprintf : (unit → ”Result) → TextWriter → TextWriterFormat<”T,”Result> → ”T Like fprintf, but calls the specified function to generate the result. kprintf : (string → ”Result) → StringFormat<”T,”Result> → ”T Like printf, but calls the specified function to generate the result. For example, these let the printing force a flush after all output has been entered onto the channel, but not before. ksprintf : (string → ”Result) → StringFormat<”T,”Result> → ”T Like sprintf, but calls the specified function to generate the result. printf : TextWriterFormat<”T> → ”T Prints formatted output to stdout. printfn : TextWriterFormat<”T> → ”T Prints formatted output to stdout, adding a newline. sprintf : StringFormat<”T> → ”T Prints to a string by using an internal string buffer and returns the result as a string. Format Specifications Format specifications are used for formatting the input or output, according to the programmers’ need. These are strings with % markers indicating format placeholders. The syntax of a Format placeholders is − %[flags][width][.precision][type] The type is interpreted as − Type Description %b Formats a bool, formatted as true or false. %c Formats a character. %s Formats a string, formatted as its contents, without interpreting any escape characters. %d, %i Formats any basic integer type formatted as a decimal integer, signed if the basic integer type is signed. %u Formats any basic integer type formatted as an unsigned decimal integer. %x Formats any basic integer type formatted as an unsigned hexadecimal integer, using lowercase letters a through f. %X Formats any basic integer type formatted as an unsigned hexadecimal integer, using uppercase letters A through F. %o Formats any basic integer type formatted as an unsigned octal integer. %e, %E, %f, %F, %g, %G Formats any basic floating point type (float, float32) formatted using a C-style floating point format specifications. %e, %E Formats a signed value having the form [-]d.dddde[sign]ddd where d is a single decimal digit, dddd is one or more decimal digits, ddd is exactly three decimal digits, and sign is + or -. %f Formats a signed value having the form [-]dddd.dddd, where dddd is one or more decimal digits. The number of digits before the decimal point depends on the magnitude of the number, and the number of digits after the decimal point depends on the requested precision. %g, %G Formats a signed value printed in f or e format, whichever is more compact for the given value and precision. %M Formats a Decimal value. %O Formats any value, printed by boxing the object and using its ToString method. %A, %+A Formats any value, printed with the default layout settings. Use %+A to print the structure of discriminated unions with internal and private representations. %a A general format specifier, requires two arguments. The first argument is a function which accepts two arguments: first, a context parameter of the appropriate type for the given formatting function (for example, a TextWriter), and second, a value to print and which either outputs or returns appropriate text. The second argument is the particular value to print. %t A general format specifier, requires one argument: a function which accepts a context parameter of the appropriate type for the given formatting function (aTextWriter) and which either outputs or returns appropriate text. Basic integer types are byte, sbyte, int16, uint16, int32, uint32, int64, uint64, nativeint, and unativeint. Basic floating point types are float and float32. The width is an optional parameter. It is an integer that indicates the minimal width of the result. For example, %5d prints an integer with at least spaces of 5 characters. Valid flags are described in the following table − Value Description 0 Specifies to add zeros instead of spaces to make up the required width. – Specifies to left-justify the result within the width specified. + Specifies to add a + character if the number is positive (to match a – sign for negative numbers). ” ” (space) Specifies to add an extra space if the number is positive (to match a – sign for negative numbers). # Invalid. Example Live Demo printf “Hello ” printf “World” printfn “” printfn “Hello ” printfn “World” printf “Hi, I”m %s and I”m a %s” “Rohit” “Medical Student” printfn “d: %f” 212.098f printfn “e: %f” 504.768f printfn “x: %g” 212.098f printfn “y: %g” 504.768f printfn “x: %e” 212.098f printfn “y: %e” 504.768f printfn “True: %b” true When you compile and execute the program, it yields the following output − Hello World Hello World Hi, I”m Rohit and I”m a Medical Studentd: 212.098000 e: 504.768000 x: 212.098 y: 504.768 x: 2.120980e+002 y: 5.047680e+002 True: true The Console Class This class is a part of the .NET framework. It represents the standard input, output, and error streams for console applications. It provides various methods for reading from and writing into the console. The following table shows the methods
F# – Exception Handling
F# – Exception Handling ”; Previous Next An exception is a problem that arises during the execution of a program. An F# exception is a response to an exceptional circumstance that arises while a program is running, such as an attempt to divide by zero. Exceptions provide a way to transfer control from one part of a program to another. F# exception handling provides the following constructs − Construct Description raise expr Raises the given exception. failwith expr Raises the System.Exception exception. try expr with rules Catches expressions matching the pattern rules. try expr finally expr Execution the finally expression both when the computation is successful and when an exception is raised. | 😕 ArgumentException A rule matching the given .NET exception type. | 😕 ArgumentException as e A rule matching the given .NET exception type, binding the name e to the exception object value. | Failure(msg) → expr A rule matching the given data-carrying F# exception. | exn → expr A rule matching any exception, binding the name exn to the exception object value. | exn when expr → expr A rule matching the exception under the given condition, binding the name exn to the exception object value. Let us start with the basic syntax of Exception Handling. Syntax Basic syntax for F# exception handling block is − exception exception-type of argument-type Where, exception-type is the name of a new F# exception type. argument-type represents the type of an argument that can be supplied when you raise an exception of this type. Multiple arguments can be specified by using a tuple type for argument-type. The try…with expression is used for exception handling in the F# language. Syntax for the try … with expression is − try expression1 with | pattern1 -> expression2 | pattern2 -> expression3 … The try…finally expression allows you to execute clean-up code even if a block of code throws an exception. Syntax for the try … finally expression is − try expression1 finally expression2 The raise function is used to indicate that an error or exceptional condition has occurred. It also captures the information about the error in an exception object. Syntax for the raise function is − raise (expression) The failwith function generates an F# exception. Syntax for the failwith function is − failwith error-message-string The invalidArg function generates an argument exception. invalidArg parameter-name error-message-string Example of Exception Handling Example 1 The following program shows the basic exception handling with a simple try… with block − Live Demo let divisionprog x y = try Some (x / y) with | 😕 System.DivideByZeroException -> printfn “Division by zero!”; None let result1 = divisionprog 100 0 When you compile and execute the program, it yields the following output − Division by zero! Example 2 F# provides an exception type for declaring exceptions. You can use an exception type directly in the filters in a try…with expression. The following example demonstrates this − Live Demo exception Error1 of string // Using a tuple type as the argument type. exception Error2 of string * int let myfunction x y = try if x = y then raise (Error1(“Equal Number Error”)) else raise (Error2(“Error Not detected”, 100)) with | Error1(str) -> printfn “Error1 %s” str | Error2(str, i) -> printfn “Error2 %s %d” str i myfunction 20 10 myfunction 5 5 When you compile and execute the program, it yields the following output − Error2 Error Not detected 100 Error1 Equal Number Error Example 3 The following example demonstrates nested exception handling − Live Demo exception InnerError of string exception OuterError of string let func1 x y = try try if x = y then raise (InnerError(“inner error”)) else raise (OuterError(“outer error”)) with | InnerError(str) -> printfn “Error:%s” str finally printfn “From the finally block.” let func2 x y = try func1 x y with | OuterError(str) -> printfn “Error: %s” str func2 100 150 func2 100 100 func2 100 120 When you compile and execute the program, it yields the following output − From the finally block. Error: outer error Error:inner error From the finally block. From the finally block. Error: outer error Example 4 The following function demonstrates the failwith function − Live Demo let divisionFunc x y = if (y = 0) then failwith “Divisor cannot be zero.” else x / y let trydivisionFunc x y = try divisionFunc x y with | Failure(msg) -> printfn “%s” msg; 0 let result1 = trydivisionFunc 100 0 let result2 = trydivisionFunc 100 4 printfn “%A” result1 printfn “%A” result2 When you compile and execute the program, it yields the following output − Divisor cannot be zero. 0 25 Example 5 The invalidArg function generates an argument exception. The following program demonstrates this − Live Demo let days = [| “Sunday”; “Monday”; “Tuesday”; “Wednesday”; “Thursday”; “Friday”; “Saturday” |] let findDay day = if (day > 7 || day < 1) then invalidArg “day” (sprintf “You have entered %d.” day) days.[day – 1] printfn “%s” (findDay 1) printfn “%s” (findDay 5) printfn “%s” (findDay 9) When you compile and execute the program, it yields the following output − Sunday Thursday Unhandled Exception: System.ArgumentException: You have entered 9. … Some other information about the file and variable causing error in the system will also be displayed, depending upon the system. Print Page Previous Next Advertisements ”;
F# – Interfaces
F# – Interfaces ”; Previous Next Interfaces provide an abstract way of writing up the implementation details of a class. It is a template that declares the methods the class must implement and expose publicly. Syntax An interface specifies the sets of related members that other classes implement. It has the following syntax − // Interface declaration: [ attributes ] type interface-name = [ interface ] [ inherit base-interface-name …] abstract member1 : [ argument-types1 -> ] return-type1 abstract member2 : [ argument-types2 -> ] return-type2 … [ end ] // Implementing, inside a class type definition: interface interface-name with member self-identifier.member1 argument-list = method-body1 member self-identifier.member2 argument-list = method-body2 // Implementing, by using an object expression: [ attributes ] let class-name (argument-list) = { new interface-name with member self-identifier.member1 argument-list = method-body1 member self-identifier.member2 argument-list = method-body2 [ base-interface-definitions ] } member-list Please note − In an interface declaration the members are not implemented. The members are abstract, declared by the abstract keyword. However you may provide a default implementation using the default keyword. You can implement interfaces either by using object expressions or by using class types. In class or object implementation, you need to provide method bodies for abstract methods of the interface. The keywords interface and end, which mark the start and end of the definition, are optional. For example, type IPerson = abstract Name : string abstract Enter : unit -> unit abstract Leave : unit -> unit Calling Interface Methods Interface methods are called through the interface, not through the instance of the class or type implementing interface. To call an interface method, you up cast to the interface type by using the :> operator (upcast operator). For example, (s :> IPerson).Enter() (s :> IPerson).Leave() The following example illustrates the concept − Example Live Demo type IPerson = abstract Name : string abstract Enter : unit -> unit abstract Leave : unit -> unit type Student(name : string, id : int) = member this.ID = id interface IPerson with member this.Name = name member this.Enter() = printfn “Student entering premises!” member this.Leave() = printfn “Student leaving premises!” type StuffMember(name : string, id : int, salary : float) = let mutable _salary = salary member this.Salary with get() = _salary and set(value) = _salary <- value interface IPerson with member this.Name = name member this.Enter() = printfn “Stuff member entering premises!” member this.Leave() = printfn “Stuff member leaving premises!” let s = new Student(“Zara”, 1234) let st = new StuffMember(“Rohit”, 34, 50000.0) (s :> IPerson).Enter() (s :> IPerson).Leave() (st :> IPerson).Enter() (st :> IPerson).Leave() When you compile and execute the program, it yields the following output − Student entering premises! Student leaving premises! Stuff member entering premises! Stuff member leaving premises! Interface Inheritance Interfaces can inherit from one or more base interfaces. The following example shows the concept − Live Demo type Interface1 = abstract member doubleIt: int -> int type Interface2 = abstract member tripleIt: int -> int type Interface3 = inherit Interface1 inherit Interface2 abstract member printIt: int -> string type multiplierClass() = interface Interface3 with member this.doubleIt(a) = 2 * a member this.tripleIt(a) = 3 * a member this.printIt(a) = a.ToString() let ml = multiplierClass() printfn “%d” ((ml:>Interface3).doubleIt(5)) printfn “%d” ((ml:>Interface3).tripleIt(5)) printfn “%s” ((ml:>Interface3).printIt(5)) When you compile and execute the program, it yields the following output − 10 15 5 Print Page Previous Next Advertisements ”;
F# – Events
F# – Events ”; Previous Next Events allow classes to send and receive messages between one another. In GUI, events are user actions like key press, clicks, mouse movements, etc., or some occurrence like system generated notifications. Applications need to respond to events when they occur. For example, interrupts. Events are used for inter-process communication. Objects communicate with one another through synchronous message passing. Events are attached to other functions; objects register callback functions to an event, and these callbacks are executed when (and if) the event is triggered by some object. The Event Class and Event Module The Control.Event<”T> Class helps in creating an observable object or event. It has the following instance members to work with the events − Member Description Publish Publishes an observation as a first class value. Trigger Triggers an observation using the given parameters. The Control.Event Module provides functions for managing event streams − Value Description add : (”T → unit) → Event<”Del,”T> → unit Runs the given function each time the given event is triggered. choose : (”T → ”U option) → IEvent<”Del,”T> → IEvent<”U> Returns a new event which fires on a selection of messages from the original event. The selection function takes an original message to an optional new message. filter : (”T → bool) → IEvent<”Del,”T> → IEvent<”T> Returns a new event that listens to the original event and triggers the resulting event only when the argument to the event passes the given function. map : (”T → ”U) → IEvent<”Del, ”T> → IEvent<”U> Returns a new event that passes values transformed by the given function. merge : IEvent<”Del1,”T> → IEvent<”Del2,”T> → IEvent<”T> Fires the output event when either of the input events fire. pairwise : IEvent<”Del,”T> → IEvent<”T * ”T> Returns a new event that triggers on the second and subsequent triggering of the input event. The Nth triggering of the input event passes the arguments from the N-1th and Nth triggering as a pair. The argument passed to the N-1th triggering is held in hidden internal state until the Nth triggering occurs. partition : (”T → bool) → IEvent<”Del,”T> → IEvent<”T> * IEvent<”T> Returns a new event that listens to the original event and triggers the first resulting event if the application of the predicate to the event arguments returned true, and the second event if it returned false. scan : (”U → ”T → ”U) → ”U → IEvent<”Del,”T> → IEvent<”U> Returns a new event consisting of the results of applying the given accumulating function to successive values triggered on the input event. An item of internal state records the current value of the state parameter. The internal state is not locked during the execution of the accumulation function, so care should be taken that the input IEvent not triggered by multiple threads simultaneously. split : (”T → Choice<”U1,”U2>) → IEvent<”Del,”T> → IEvent<”U1> * IEvent<”U2> Returns a new event that listens to the original event and triggers the first resulting event if the application of the function to the event arguments returned a Choice1Of2, and the second event if it returns a Choice2Of2. Creating Events Events are created and used through the Event class. The Event constructor is used for creating an event. Example type Worker(name : string, shift : string) = let mutable _name = name; let mutable _shift = shift; let nameChanged = new Event<unit>() (* creates event *) let shiftChanged = new Event<unit>() (* creates event *) member this.Name with get() = _name and set(value) = _name <- value member this.Shift with get() = _shift and set(value) = _shift <- value After this you need to expose the nameChanged field as a public member, so that the listeners can hook onto the event for which, you use the Publish property of the event − type Worker(name : string, shift : string) = let mutable _name = name; let mutable _shift = shift; let nameChanged = new Event<unit>() (* creates event *) let shiftChanged = new Event<unit>() (* creates event *) member this.NameChanged = nameChanged.Publish (* exposed event handler *) member this.ShiftChanged = shiftChanged.Publish (* exposed event handler *) member this.Name with get() = _name and set(value) = _name <- value nameChanged.Trigger() (* invokes event handler *) member this.Shift with get() = _shift and set(value) = _shift <- value shiftChanged.Trigger() (* invokes event handler *) Next, you add callbacks to event handlers. Each event handler has the type IEvent<”T>, which provides several methods − Method Description val Add : event:(”T → unit) → unit Connects a listener function to the event. The listener will be invoked when the event is fired. val AddHandler : ”del → unit Connects a handler delegate object to the event. A handler can be later removed using RemoveHandler. The listener will be invoked when the event is fired. val RemoveHandler : ”del → unit Removes a listener delegate from an event listener store. The following section provides a complete example. Example The following example demonstrates the concept and techniques discussed above − Live Demo type Worker(name : string, shift : string) = let mutable _name = name; let mutable _shift = shift; let nameChanged = new Event<unit>() (* creates event *) let shiftChanged = new Event<unit>() (* creates event *) member this.NameChanged = nameChanged.Publish (* exposed event handler *) member this.ShiftChanged = shiftChanged.Publish (* exposed event handler *) member this.Name with get() = _name and set(value) = _name <- value nameChanged.Trigger() (* invokes event handler *) member this.Shift with get() = _shift and set(value) = _shift <- value shiftChanged.Trigger() (* invokes event handler *) let wk = new Worker(“Wilson”, “Evening”) wk.NameChanged.Add(fun () -> printfn “Worker changed name! New name: %s” wk.Name) wk.Name <- “William” wk.NameChanged.Add(fun () -> printfn “– Another handler attached to NameChanged!”) wk.Name <- “Bill” wk.ShiftChanged.Add(fun () -> printfn “Worker changed shift! New shift: %s” wk.Shift) wk.Shift <- “Morning” wk.ShiftChanged.Add(fun () -> printfn “– Another handler attached to ShiftChanged!”) wk.Shift <- “Night” When you compile and execute the program, it yields the following output
F# – Discussion
Discuss F# ”; Previous Next F# helps you in the daily development of the mainstream commercial business software. This tutorial provides a brief knowledge about F# and its features, and also provides the various structures and syntaxes of its methods and functions. Print Page Previous Next Advertisements ”;
F# – Discriminated Unions
F# – Discriminated Unions ”; Previous Next Unions, or discriminated unions allows you to build up complex data structures representing well-defined set of choices. For example, you need to build an implementation of a choice variable, which has two values yes and no. Using the Unions tool, you can design this. Syntax Discriminated unions are defined using the following syntax − type type-name = | case-identifier1 [of [ fieldname1 : ] type1 [ * [ fieldname2 : ] type2 …] | case-identifier2 [of [fieldname3 : ]type3 [ * [ fieldname4 : ]type4 …] … Our simple implementation of ,choice, will look like the following − type choice = | Yes | No The following example uses the type choice − Live Demo type choice = | Yes | No let x = Yes (* creates an instance of choice *) let y = No (* creates another instance of choice *) let main() = printfn “x: %A” x printfn “y: %A” y main() When you compile and execute the program, it yields the following output − x: Yes y: No Example 1 The following example shows the implementation of the voltage states that sets a bit on high or low − Live Demo type VoltageState = | High | Low let toggleSwitch = function (* pattern matching input *) | High -> Low | Low -> High let main() = let on = High let off = Low let change = toggleSwitch off printfn “Switch on state: %A” on printfn “Switch off state: %A” off printfn “Toggle off: %A” change printfn “Toggle the Changed state: %A” (toggleSwitch change) main() When you compile and execute the program, it yields the following output − Switch on state: High Switch off state: Low Toggle off: High Toggle the Changed state: Low Example 2 Live Demo type Shape = // here we store the radius of a circle | Circle of float // here we store the side length. | Square of float // here we store the height and width. | Rectangle of float * float let pi = 3.141592654 let area myShape = match myShape with | Circle radius -> pi * radius * radius | Square s -> s * s | Rectangle (h, w) -> h * w let radius = 12.0 let myCircle = Circle(radius) printfn “Area of circle with radius %g: %g” radius (area myCircle) let side = 15.0 let mySquare = Square(side) printfn “Area of square that has side %g: %g” side (area mySquare) let height, width = 5.0, 8.0 let myRectangle = Rectangle(height, width) printfn “Area of rectangle with height %g and width %g is %g” height width (area myRectangle) When you compile and execute the program, it yields the following output − Area of circle with radius 12: 452.389 Area of square that has side 15: 225 Area of rectangle with height 5 and width 8 is 40 Print Page Previous Next Advertisements ”;
F# – Structures
F# – Structures ”; Previous Next A structure in F# is a value type data type. It helps you to make a single variable, hold related data of various data types. The struct keyword is used for creating a structure. Syntax Syntax for defining a structure is as follows − [ attributes ] type [accessibility-modifier] type-name = struct type-definition-elements end // or [ attributes ] [<StructAttribute>] type [accessibility-modifier] type-name = type-definition-elements There are two syntaxes. The first syntax is mostly used, because, if you use the struct and end keywords, you can omit the StructAttribute attribute. The structure definition elements provide − Member declarations and definitions. Constructors and mutable and immutable fields. Members and interface implementations. Unlike classes, structures cannot be inherited and cannot contain let or do bindings. Since, structures do not have let bindings; you must declare fields in structures by using the val keyword. When you define a field and its type using val keyword, you cannot initialize the field value, instead they are initialized to zero or null. So for a structure having an implicit constructor, the val declarations be annotated with the DefaultValue attribute. Example The following program creates a line structure along with a constructor. The program calculates the length of a line using the structure − Live Demo type Line = struct val X1 : float val Y1 : float val X2 : float val Y2 : float new (x1, y1, x2, y2) = {X1 = x1; Y1 = y1; X2 = x2; Y2 = y2;} end let calcLength(a : Line)= let sqr a = a * a sqrt(sqr(a.X1 – a.X2) + sqr(a.Y1 – a.Y2) ) let aLine = new Line(1.0, 1.0, 4.0, 5.0) let length = calcLength aLine printfn “Length of the Line: %g ” length When you compile and execute the program, it yields the following output − Length of the Line: 5 Print Page Previous Next Advertisements ”;
F# – Generics
F# – Generics ”; Previous Next Generics allow you to delay the specification of the data type of programming elements in a class or a method, until it is actually used in the program. In other words, generics allow you to write a class or method that can work with any data type. You write the specifications for the class or the method, with substitute parameters for data types. When the compiler encounters a constructor for the class or a function call for the method, it generates code to handle the specific data type. In F#, function values, methods, properties, and aggregate types such as classes, records, and discriminated unions can be generic. Generic constructs contain at least one type parameter. Generic functions and types enable you to write code that works with a variety of types without repeating the code for each type. Syntax Syntax for writing a generic construct is as follows − // Explicitly generic function. let function-name<type-parameters> parameter-list = function-body // Explicitly generic method. [ static ] member object-identifer.method-name<type-parameters> parameter-list [ return-type ] = method-body // Explicitly generic class, record, interface, structure, // or discriminated union. type type-name<type-parameters> type-definition Examples Live Demo (* Generic Function *) let printFunc x y = printfn “%A, %A” x y printFunc<float> 10.0 20.0 When you compile and execute the program, it yields the following output − 10.0, 20.0 You can also make a function generic by using the single quotation mark syntax − Live Demo (* Generic Function *) let printFunction (x: ”a) (y: ”a) = printfn “%A %A” x y printFunction 10.0 20.0 When you compile and execute the program, it yields the following output − 10.0 20.0 Please note that when you use generic functions or methods, you might not have to specify the type arguments. However, in case of an ambiguity, you can provide type arguments in angle brackets as we did in the first example. If you have more than one type, then you separate multiple type arguments with commas. Generic Class Like generic functions, you can also write generic classes. The following example demonstrates this − Live Demo type genericClass (x: ”a) = do printfn “%A” x let gr = new genericClass<string>(“zara”) let gs = genericClass( seq { for i in 1 .. 10 -> (i, i*i) } ) When you compile and execute the program, it yields the following output − “zara” seq [(1, 1); (2, 4); (3, 9); (4, 16); …] Print Page Previous Next Advertisements ”;