拿 C 搞函式式程式設計 1

2022-01-09 21:11:21 字數 2588 閱讀 8772

最近閒下來了,準備出乙個 c# 搞 fp 的合集。本合集所有**均以 c# 8 為示例。

可能你說,為什麼要這麼做呢?回答:為了好玩。另外,意義黨們請 gun cu ke!

c# 有委託,而且有 func<> 和 action<>,可以說函式被視為一等功名,跟 int、bool 等型別並沒有什麼區別。那麼很多事情就簡單了。

什麼是純函式呢?純函式就是 f(x),它們接收引數,得到結果,並且相同的引數得到的結果一定是相同的,用對映來說,它是滿射的。另外這個函式不會改變任何的狀態值,它是無***的。

首先,有乙個東西讓我覺得不爽,那就是一般來說 c# 裡的函式呼叫不是柯里化的,這也就意味著我沒法乙個乙個傳引數進去,也沒法把傳了一部分引數的呼叫作為乙個新函式拿去給別的地方用,那要怎麼辦呢?

自己動手,豐衣足食!

乙個標準的加法函式可以這麼寫:

var function = new func((x, y) => x +y);

function(

1, 2); //

returns 3

如果我們想以柯里化形式呼叫的話,理想狀態是這麼個樣子的:

function 1

2

但是這個括號我們是省不了的,所以這樣也是可以接受的:

function(1)(2);

我們看一下這個呼叫形式,不就是 func> 嘛!so easy~

我們只需要把 func轉化為 func>:

func> currying(funcf) 

=> x => y => f(x, y);

這樣寫就 ok 啦。進一步改造成擴充套件方法:

public

static

class

curryingextensions

於是我們只需要:

var function = new func((x, y) => x +y)

.currying();

function(

1)(2); //

returns 3

就可以採用柯里化形式呼叫該函式啦。

進一步我們用泛型改造,讓柯里化適用於任何型別:

public

static

class

curryingextensions

如果遇到更多引數,我們只需要給這個靜態類裡面再加乙個擴充套件方法即可。

那 action<> 呢?這個東西在我看來完全就是***,具體下方有講,我們不用他(逃

什麼是 unit 呢?unit 就是任何函式呼叫後如果沒有結果,就會返回的乙個東西。

可能你說,void 不就可以了?

但是如果乙個純函式,它沒有返回值(即 action<>),意味著這個函式它有輸入沒輸出,那這個函式除了能用來產生***之外,就什麼都幹不了了。這不清真!

因此我們需要乙個 unit 來代替 void,偷個懶,這個 unit 就用 ulong 來代替吧。

什麼叫做高階函式,把函式當作引數傳給另乙個函式,接收這個函式引數的函式就叫做高階函式。

舉個例子:f(g(x)),f 即高階函式。

假設我們現在要開乙個超市,超市有很多的產品,每種產品**不同,不同產品可能還有各自的折扣。我們有很多種快樂水,每種快樂水**不一樣,可口快樂水 3.5 塊,百事快樂水 3 塊,麥當勞快樂水 9 塊,快樂水**計算函式:

float price, int number) => number *price)

.currying();

//);

);超市可能有折扣,a 超市不打折,b 超市打八折,計算**函式:

var calcprice = new funcint, float>, float, int, float>((calc, discount, number) => discount *calc(number))

.currying();

//呼叫:calcprice(快樂水**計算函式)(超市折扣)(快樂水件數);

現在我們分別在 a 超市買百事快樂水、b 超市買可口快樂水,麥當勞的太貴了我們不買,**計算函式為:

var pricecalca = pepsipricecalc(1); //

a 超市

var pricecalcb = cocapricecalc(0.8f); //

b 超市

最後我們在 a 超市買了 3 瓶百事快樂水,b 超市買了 5 瓶可口快樂水,計算總價:

var pricea = pricecalca(3

);var priceb = pricecalcb(5

);var total = pricea + priceb;

最後得到 total = 23 元。

可以看到這些函式都是可拆卸並且可以隨意組合的,而且滿足 f(g(x)) = g(f(x))。

貼上完整**示例:

using

system;

namespace

colamarket

class

program

}}

1 函式式程式設計

關注點不同 命令式程式設計關注的是怎樣做,告訴程式怎樣做,才能達到乙個功能 而函式式是關注做什麼,不需要告訴怎麼做,不需要關注實現的細節,告訴它要實現什麼功能即可 舉例 在一堆數字裡面找到最小的值,兩種實現方式如下 什麼是函式式程式設計 public class whyuselambda old n...

Scala函式式程式設計 1

val a list 1,2,3,4 遍歷迴圈 for i a print i for i 0 to a.length 1 println a i for i 0until a.length print a i foreach迭代列印 a.foreach x int println x 使用型別推斷...

c 函式式程式設計小記

函式指標的定義格式為 ret type var name arg list 表示返回值為ret type,引數列表為arg list的函式指標var name.如int p int,int 表示返回值為int,引數為兩個int型的函式指標p。以函式指標作為形參,即可實現函式名作為引數,由另乙個函式呼...