C++模版編程實(shí)現(xiàn)Haskell的函數(shù)模式匹配特性[圖]

C++模版編程實(shí)現(xiàn)Haskell的函數(shù)模式匹配特性[圖]:
大神 Bartosz Milewski 在2009年寫了一篇文章《What Does Haskell Have to Do with C++?》,使用C++實(shí)現(xiàn)Haskell函數(shù)式編程語(yǔ)言的一些特性?!緜魉烷T在文末】
其中有這樣一段例子:
// code 1
1.template<int n>class fact {
2.public:

成都創(chuàng)新互聯(lián)長(zhǎng)期為上1000+客戶提供的網(wǎng)站建設(shè)服務(wù),團(tuán)隊(duì)從業(yè)經(jīng)驗(yàn)10年,關(guān)注不同地域、不同群體,并針對(duì)不同對(duì)象提供差異化的產(chǎn)品和服務(wù);打造開放共贏平臺(tái),與合作伙伴共同營(yíng)造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為湖北企業(yè)提供專業(yè)的網(wǎng)站設(shè)計(jì)制作、成都網(wǎng)站建設(shè),湖北網(wǎng)站改版等技術(shù)服務(wù)。擁有十多年豐富建站經(jīng)驗(yàn)和眾多成功案例,為您定制開發(fā)。

  1. staticconstint value = n * fact<n -1>::value;
    4.};
  2. 6.template<>class fact<0>{// specialization for n = 0
    7.public:

  3. staticconstint value =1;
    9.};
    注:原文中使用的是struct關(guān)鍵字,這里改為class并加上了public
    我猜,你沒看懂。沒關(guān)系,我們先跳過上面這一段有著【令人恐怖的語(yǔ)法】的C++模版代碼。
    上面的例子想干嘛呢?其實(shí)它只是想計(jì)算n的階乘。
    C++模版編程實(shí)現(xiàn)Haskell的函數(shù)模式匹配特性[圖]
    如果你在C語(yǔ)言里面學(xué)過遞歸,應(yīng)該知道下面這段計(jì)算階乘的遞歸函數(shù)
    // code 2
    int fact(int n){
    if(0== n )
    return1; //0階問題答案。0! 等于1
    else
    return( n fact( n -1)); //問題降階:n階->n-1階
    }
    它的效果就等于下面的代碼
    // code 3
    int fact2(int n){ // 用 for 循環(huán)計(jì)算階乘
    int p =1;
    for(int i=n; i >=1; i--)
    p
    = i;
    return p;
    }
    那么,第一段代碼(code1)與第二段代碼(code2)的區(qū)別在哪里呢?
    區(qū)別在于,code1是在編譯時(shí)(由編譯器)計(jì)算的,code2是在運(yùn)行時(shí)(就是代碼運(yùn)行的時(shí)候)計(jì)算的。
    現(xiàn)在來解釋一下code1 (部分根據(jù)Bartosz Milewski文中的說法)
    // code 1
    / 第1行代碼聲明了一個(gè)類模版 fact。
    這個(gè)模版接受一個(gè)“非類型參數(shù)”n,
    n是整數(shù)。
    /
    1.template<int n>class fact {
    2.public:
    / 第3行代碼聲明了一個(gè)靜態(tài)整型常量
    成員 value。而 value 的值是使用
    遞歸模版表示的
    /
  4. staticconstint value = n * fact<n -1>::value;
    4.};
  5. / 第6行代碼是“特化”類模版fact,
    也就是顯式地給出某種類型參數(shù)的
    類模板的一個(gè)實(shí)例的代碼,而非由
    編譯器生成。
    在這里,是給出了參數(shù)n為0時(shí)模板
    fact的代碼。這樣,編譯器不會(huì)再
    根據(jù)類模版fact生成n=0時(shí)的代碼
    關(guān)于模版特化,詳見文末鏈接
    /
    6.template<>class fact<0>{// specialization for n = 0
    7.public:

  6. static const int value = 1;
  7. };
    / 根據(jù)C++規(guī)范,模版特化的代碼必須
    放到模版聲明之后。
    因此上面的代碼看上去好像先處理了
    由n階到n-1階的降階問題,然后再給
    出了0階的解答
    這可不像code2。code2中有if/else,
    因此可以把降階代碼與0階解答代碼調(diào)
    換先后次序(當(dāng)然if條件得改)。
    /
    那么這個(gè)用模版計(jì)算階乘的代碼(類?)該怎么用呢?如下:
    cout <<"Factorial of 0 = "<< fact<0>::value << endl;
    其中,C++編譯器會(huì)為“fact<0>::value”這個(gè)調(diào)用匹配最合適的模版代碼,也就是code1中的第6-9行代碼。
    如果用非零參數(shù)調(diào)用呢?
    cout <<"Factorial of 8 = "<< fact<8>::value << endl;
    其中,C++編譯器會(huì)為“fact<8>::value”這個(gè)調(diào)用匹配code1中的第1-4行代碼。
    前面blahblhaaaaaaaaaaaah講了一大堆,其實(shí)都不是正經(jīng)事兒。
    正經(jīng)是下面的Haskell代碼:
    //code 4
  8. fact 0=1
  9. fact n = n * fact (n -1)
    上面兩行代碼定義了函數(shù)fact。fact是函數(shù)名,fact的后面、等號(hào)的前面是函數(shù)的參數(shù)。等號(hào)后面是函數(shù)體,函數(shù)體的計(jì)算結(jié)果就是fact函數(shù)的返回值。
    當(dāng)程序員調(diào)用【fact 8】的時(shí)候(參數(shù)是8,因?yàn)镠askell函數(shù)調(diào)用一般不像C++那樣給參數(shù)加括號(hào)),Haskell會(huì)將之匹配到上面代碼的第2行。誰動(dòng)了我的奶酪讀書筆記(http://www.simayi.net/dushubiji/6208.html)摘抄好詞好句及感悟賞析,這種參數(shù)匹配,是Haskell特有的函數(shù)聲明與調(diào)用方式。

    所以前面的code1中C++模版代碼,就是在模仿 code4 中的Haskell代碼。
    下面給出一個(gè)完整的Haskell程序
    moduleFactwhere
    importSystem.IO
    fact::Integer->Integer
    fact0=1
    fact n = n * fact (n-1)
    main::IO()
    main=do
    putStrLn $"8! = "++ show (fact 8)
    putStrLn $"88! = "++ show (fact 88)
    上面的代碼輸出結(jié)果是:
    8! = 40320
    88! =185482642257398439114796845645546284380220968949399346684421580986889562184028199319100141244804501828416633516851200000000000000000000
    Haskell對(duì)C++說:我能算88!,你行嗎?
    C++說:你欺負(fù)人!

本文標(biāo)題:C++模版編程實(shí)現(xiàn)Haskell的函數(shù)模式匹配特性[圖]
網(wǎng)站URL:http://bm7419.com/article34/gocdse.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供品牌網(wǎng)站建設(shè)響應(yīng)式網(wǎng)站、網(wǎng)站改版、動(dòng)態(tài)網(wǎng)站網(wǎng)站排名、云服務(wù)器

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

成都seo排名網(wǎng)站優(yōu)化