Skip to main content

  | मौसम…

411 समाचार
Public archive edition · Attributed source reporting with original dates · AI drafts are excluded

411 REFERENCE · Wikibooks

F Sharp Programming/Operator Overloading

Reference material by Wikibooks contributors. This retains its source identity and is not 411 news reporting.

F Sharp Programming Exception Handling Classes Operator Overloading Operator overloading allows programmers to provide new behavior for the default operators in F#. In practice, programmers overload operators to provide a simplified syntax for objects which can be combined mathematically. Using Operators You've already used operators: let sum = x + y Here + is example of using a mathematical addition operator. Operator Overloading Operators are functions with special names, enclosed in brackets. They must be defined as static class members. Here's an example on declaring + operator on complex numbers: type Complex = { Re: double Im: double } static member ( + ) (left: Complex, right: Complex) = { Re = left.Re + right.Re; Im = left.Im + right.Im } In FSI, we can add two complex numbers as follows: > let first = { Re = 1.0; Im = 7.0 };; val first : Complex > let second = { Re = 2.0; Im = -10.5 };; val second : Complex > first + second;; val it : Complex = {Re = 3.0; Im = -3.5;} Defining New Operators In addition to overloading existing operators, its possible to define new operators. The names of custom operators can only be one or more of the following characters: !%&*+-./<=>?@^|~ F# supports two types of operators: infix operators and prefix operators. Infix operators An infix operator takes two arguments, with the operator appearing in between both arguments (i.e. arg1 {op} arg2). We can define our own infix operators using the syntax: let (op) arg1 arg2 = ... In addition to mathematical operators, F# has a variety of infix operators defined as part of its library, for example: let inline (|>) x f = f x let inline (::) hd tl = Cons(hd, tl) let inline (:=) (x : 'a ref) value = x.contents <- value Let's say we're writing an application which performs a lot of regex matching and replacing. We can match text using Perl-style operators by defining our own operators as follows: open System.Text.RegularExpressions let (=~) input pattern = Regex.IsMatch(input, pattern) let main() = printfn "cat =~ dog: %b" ("cat" =~ "dog") printfn "cat =~ cat|dog: %b" ("cat" =~ "cat|dog") printfn "monkey =~ monk*: %b" ("monkey" =~ "monk*") main() This program outputs the following: cat =~ dog: false cat =~ cat|dog: true monkey =~ monk*: true Prefix Operators Prefix operators take a single argument which appears to the right side of the operator ({op}argument). You've already seen how the ! operator is defined for ref cells: type 'a ref = { mutable contents : 'a } let (!) (x : 'a ref) = x.contents Let's say we're writing a number crunching application, and we wanted to define some operators that work on lists of numbers. We might define some prefix operators in fsi as follows: > let ( !+ ) l = List.reduce ( + ) l let ( !- ) l = List.reduce ( - ) l let ( !* ) l = List.reduce ( * ) l let ( !/ ) l = List.reduce ( / ) l;; val ( !+ ) : int list -> int val ( !- ) : int list -> int val ( !* ) : int list -> int val ( !/ ) : int list -> int > !* [2; 3; 5];; val it : int = 30 > !+ [2; 3; 5];; val it : int = 10 > !- [2; 3; 7];; val it : int = -8 > !/ [100; 10; 2];; val it : int = 5 F Sharp Programming Exception Handling Classes