跳轉到內容

F# 程式設計/運算子過載

來自華夏公益教科書,開放的書籍,開放的世界
上一頁:異常處理 索引 下一頁:類
F#:運算子過載

運算子過載允許程式設計師為 F# 中的預設運算子提供新行為。在實踐中,程式設計師過載運算子以提供一種簡化的語法,用於可以數學組合的物件。

使用運算子

[編輯 | 編輯原始碼]

你已經使用過運算子了

let sum = x + y

這裡 + 是使用數學加法運算子的示例。

運算子過載

[編輯 | 編輯原始碼]

運算子是具有特殊名稱的函式,用括號括起來。它們必須定義為靜態類成員。以下是在複數上宣告 + 運算子的示例

type Complex =
    {   Re: double
        Im: double }
    static member ( + ) (left: Complex, right: Complex) =
        { Re = left.Re + right.Re; Im = left.Im + right.Im }

在 FSI 中,我們可以按如下方式新增兩個複數

> 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;}

定義新運算子

[編輯 | 編輯原始碼]

除了過載現有的運算子之外,還可以定義新的運算子。自定義運算子的名稱只能是以下一個或多個字元

!%&*+-./<=>?@^|~

F# 支援兩種型別的運算子:中綴運算子和字首運算子。

中綴運算子

[編輯 | 編輯原始碼]

中綴運算子接受兩個引數,運算子出現在兩個引數之間(即 arg1 {op} arg2)。我們可以使用以下語法定義自己的中綴運算子

let (op) arg1 arg2 = ...

除了數學運算子之外,F# 還將其庫中定義了許多中綴運算子,例如

let inline (|>) x f = f x
let inline (::) hd tl = Cons(hd, tl)
let inline (:=) (x : 'a ref) value = x.contents <- value

假設我們正在編寫一個執行大量正則表示式匹配和替換的應用程式。我們可以透過定義自己的運算子來使用 Perl 風格的運算子匹配文字,如下所示

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

該程式輸出以下內容

cat =~ dog: false
cat =~ cat|dog: true
monkey =~ monk*: true

字首運算子

[編輯 | 編輯原始碼]

字首運算子接受一個引數,該引數出現在運算子的右側({op}argument)。你已經看到 ! 運算子是如何為 ref 單元格定義的

type 'a ref = { mutable contents : 'a }
let (!) (x : 'a ref) = x.contents

假設我們正在編寫一個數字處理應用程式,我們想要定義一些在數字列表上工作的運算子。我們可能會在 fsi 中定義一些字首運算子,如下所示

> 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
上一頁:異常處理 索引 下一頁:類
華夏公益教科書