【F#從入門到實(shí)戰(zhàn)】03. F#自定義操作符
歡迎大家來(lái)到【F#從入門到實(shí)戰(zhàn)】,在這里我將分享關(guān)于F#編程語(yǔ)言的系列文章,帶大家一起去學(xué)習(xí)和成長(zhǎng),并探索函數(shù)編程語(yǔ)言F#這個(gè)有趣的世界。所有文章都會(huì)結(jié)合示例代碼和筆者的經(jīng)驗(yàn)進(jìn)行講解,真心想把十余年的IT經(jīng)驗(yàn)分享給大家,希望對(duì)您有所幫助,文章中也定有不足之處,請(qǐng)海涵!本系統(tǒng)文章將從F#基本語(yǔ)法入手,逐步通過(guò)自定義類型來(lái)實(shí)現(xiàn)數(shù)學(xué)表達(dá)式的各種常見(jiàn)解析操作,如對(duì)表達(dá)式進(jìn)行求值、化簡(jiǎn)、展開(kāi)、求導(dǎo)和求積分等。此系統(tǒng)博文也是了解和實(shí)現(xiàn)一個(gè)簡(jiǎn)易的計(jì)算機(jī)代數(shù)系統(tǒng)的基礎(chǔ)。
下面給出【F#從入門到實(shí)戰(zhàn)】系統(tǒng)專題文章的目錄:
【F#從入門到實(shí)戰(zhàn)】01. F#語(yǔ)言快速入門
【F#從入門到實(shí)戰(zhàn)】02. F#數(shù)組常見(jiàn)用法
【F#從入門到實(shí)戰(zhàn)】03. F#自定義操作符
【F#從入門到實(shí)戰(zhàn)】04. F#5.0新特征總結(jié)
【F#從入門到實(shí)戰(zhàn)】05. F#表達(dá)式求值
【F#從入門到實(shí)戰(zhàn)】06. F#表達(dá)式化簡(jiǎn)
【F#從入門到實(shí)戰(zhàn)】07. F#表達(dá)式展開(kāi)
【F#從入門到實(shí)戰(zhàn)】08. F#大整數(shù)階乘
【F#從入門到實(shí)戰(zhàn)】09. F#表達(dá)式求導(dǎo)
【F#從入門到實(shí)戰(zhàn)】10. F#表達(dá)式積分
【F#從入門到實(shí)戰(zhàn)】11. F#庫(kù)FParsec入門
【F#從入門到實(shí)戰(zhàn)】12. F#庫(kù)FParsec解析表達(dá)式
【F#從入門到實(shí)戰(zhàn)】13. F#庫(kù)FParsec實(shí)現(xiàn)求導(dǎo)符號(hào)計(jì)算
【F#從入門到實(shí)戰(zhàn)】14. F#實(shí)現(xiàn)分部積分法
下面將正式開(kāi)始本文的介紹:
我們知道,不少編程語(yǔ)言都支持自定義操作符,特別是對(duì)于數(shù)學(xué)相關(guān)領(lǐng)域的應(yīng)用來(lái)說(shuō),自定義類型上的操作符可以大大簡(jiǎn)化代碼,提高程序可讀性。對(duì)于F#來(lái)說(shuō),支持全局的自定義操作符和附屬于特定類型的操作符。這里需要注意的就是,全局自定義操作符需要慎用,他可能會(huì)覆蓋默認(rèn)的操作符。
下面我們定義一個(gè)全局操作符,具體示例如下:
//全局操作符,覆蓋默認(rèn)的 let inline (+)(a : float)(b : float) = 2. * a * b ;;
在F#交互環(huán)境下(;;為結(jié)束標(biāo)志),此示例執(zhí)行如下:
此時(shí),輸入? 2. + 3. 的計(jì)算結(jié)果為12.0 。其中的2.是2.0的簡(jiǎn)寫,代表float類型。另外,如果此時(shí)輸入2 + 3 則提示錯(cuò)誤,因?yàn)榇藶閕nt類型,而定義的操作符參數(shù)類型是float,不兼容。
還有一類就是對(duì)于自定義類型上的自定義操作符。這種比較常見(jiàn),下面給出一個(gè)自定義復(fù)數(shù)類型,并給出自定義操作符的示例。
module YdMath //https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/operator-overloading type Complex = { Real : float Imaginary : float } static member (+) (f1 : Complex, f2 : Complex) = let cr = f1.Real + f2.Real let ci = f1.Imaginary + f2.Imaginary {Real=cr ; Imaginary = ci} static member (-) (f1 : Complex, f2 : Complex) = let cr = f1.Real - f2.Real let ci = f1.Imaginary - f2.Imaginary {Real=cr ; Imaginary = ci} override this.ToString() = if (this.Imaginary = 0.) then this.Real.ToString() else this.Real.ToString() + "+" + this.Imaginary.ToString()+"i"
從數(shù)學(xué)上來(lái)說(shuō),復(fù)數(shù)(Complex)具有一個(gè)實(shí)部(Real)和一個(gè)虛部(Imaginary) ,這里的話,用float類型來(lái)代表每個(gè)部分的數(shù)值類型。其中的static member定義了一個(gè)靜態(tài)成員方法,但它的函數(shù)名是一個(gè)操作符,可實(shí)現(xiàn)自定義操作符功能。這里簡(jiǎn)單的定義了一個(gè)復(fù)數(shù)的加法和減法操作。并override重寫了ToString方法。最后,我們用如下代碼段進(jìn)行自定義操作符測(cè)試:
let c1 = { Real = 3. ; Imaginary = 5. } let c2 = { Real = 2. ; Imaginary = 3. } let c3 = c1 + c2 let c4 = c1 - c2 printfn "(%s) + (%s) = %s" (c1.ToString()) (c2.ToString()) (c3.ToString()) printfn "(%s) - (%s) = %s" (c1.ToString()) (c2.ToString()) (c4.ToString())
運(yùn)行此示例,結(jié)果如下:
(3+5i) + (2+3i) = 5+8i (3+5i) - (2+3i) = 1+2i
最后,再給出一個(gè)根據(jù)官方文檔示例修改的自定義操作符:
let rec hcf a b = if a = 0. then b elif a
執(zhí)行測(cè)試代碼示例如下:
let f1 = { fz = 2.; fm = 5.} let f2 = { fz = 1.; fm = 6.} let f = f1 + f2 printfn "(%s) + (%s) = %s" (f1.ToString()) (f2.ToString()) (f.ToString()) let f = f1 - f2 printfn "(%s) - (%s) = %s" (f1.ToString()) (f2.ToString()) (f.ToString()) let f = f1 * f2 printfn "(%s) * (%s) = %s" (f1.ToString()) (f2.ToString()) (f.ToString()) let f = f1 / f2 printfn "(%s) / (%s) = %s" (f1.ToString()) (f2.ToString()) (f.ToString())
執(zhí)行示例結(jié)果如下:
(2/5) + (1/6) = 17/30 (2/5) - (1/6) = 7/30 (2/5) * (1/6) = 1/15 (2/5) / (1/6) = 12/5
面向?qū)ο缶幊?/p>
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。