找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
  • 网友反映远安桃花岛步道破损隐患,住建部门火速处置,官方留言却遭平台屏蔽引唏嘘

    网友反映远安桃花岛步道破损隐患,住建部门

  • 网曝远安桃花岛上惊现安全隐患,钉子都出来了,周边都是孩子在玩耍

    网曝远安桃花岛上惊现安全隐患,钉子都出来

  • 被网友举报远安北万路上这辆挂人后视镜直接走掉的鄂A本田,罚单来了

    被网友举报远安北万路上这辆挂人后视镜直接

  • 网友举报这辆半挂竟公然在远安泉水冲那里闯红灯,别急,罚单已到位!

    网友举报这辆半挂竟公然在远安泉水冲那里闯

  • 好消息!武陵峡果园杨梅开园啦!老板发福利啦

    好消息!武陵峡果园杨梅开园啦!老板发福利

  • 精装修门面出租:无转让费!周边配套齐全,房东(胡)

    精装修门面出租:无转让费!周边配套齐全,

  • 厕所顶部漏水半年多维权困难 寻求帮助

    厕所顶部漏水半年多维权困难 寻求帮助

  • 远安G347国道上这辆大货车,你的罚单来了

    远安G347国道上这辆大货车,你的罚单来了

  • 紧急提醒:远安县刚刚发布暴雨橙色预警,注意避险防范

    紧急提醒:远安县刚刚发布暴雨橙色预警,注

  • 【招聘保洁熟手】

    【招聘保洁熟手】

  • 襄阳发布警情通报

    襄阳发布警情通报

  • 吐槽一下家门口的清洗街道车😔😔

    吐槽一下家门口的清洗街道车😔😔

  • 险象环生!远安万山弯道五菱神车逆行别车,罚单来了

    险象环生!远安万山弯道五菱神车逆行别车,

  • 突发!刚刚远安这条网红彩虹路边,翻了一辆车

    突发!刚刚远安这条网红彩虹路边,翻了一辆

  • 远安凤凰湾门口路段这位女司机,你的罚单来了

    远安凤凰湾门口路段这位女司机,你的罚单来

  • 【小董有个友好请求🫡】

    【小董有个友好请求🫡】

  • 一串红提,宛如秋日里的一抹亮色...

    一串红提,宛如秋日里的一抹亮色...

  • 远安汽摩协会与远安特校十年相伴,童心同行

    远安汽摩协会与远安特校十年相伴,童心同行

  • 【五月·共勉】

    【五月·共勉】

  • 当阳市公安局玉泉派出所原指导员朱心维接受纪律审查和监察调查

    当阳市公安局玉泉派出所原指导员朱心维接受

  • 远安广坪路段这辆奥迪,你的行为太危险了,你就不怕成了夹心饼干吗

    远安广坪路段这辆奥迪,你的行为太危险了,

  • 在远安洋坪路段违法超车的这辆车,你的罚单刚刚出来了

    在远安洋坪路段违法超车的这辆车,你的罚单

  • 这辆车在远安县解放路与凤德路交汇路口违停,极大交通隐患

    这辆车在远安县解放路与凤德路交汇路口违停

  • 网友反映远安城区这里的行道树上长满了白蚁,观之肉麻!不知道该找谁治

    网友反映远安城区这里的行道树上长满了白蚁

  • 【上午9点把门锁, 小飞侠这是要闹哪出? 】

    【上午9点把门锁, 小飞侠这是要闹哪出? 】

  • 湖北安广陶瓷招聘销售跟单

    湖北安广陶瓷招聘销售跟单

  • 今晚,调油价!

    今晚,调油价!

  • 必须曝光!今天上午,远安嫘祖镇广坪路段这辆婚庆公司的轻卡强行超车肇事逃逸

    必须曝光!今天上午,远安嫘祖镇广坪路段这

  • 坚强的小米辣

    坚强的小米辣

  • 远安人,这个“2026年度综合补贴”是诈骗!

    远安人,这个“2026年度综合补贴”是诈骗!

  • 查看: 8069|回复: 1

    C++模版编程实现Haskell的函数模式匹配特性[图]

    [复制链接]
    • 打卡等级:无名新人
    • 打卡总天数:1
    • 打卡月天数:0
    • 打卡总奖励:10
    • 最近打卡:2023-06-13 20:58:02
         
    荆楚不肖生 发表于 2018-7-18 15:50 | 显示全部楼层 |阅读模式 来自 中国–湖北–宜昌 电信

    赶紧注册,享受更多功能!查看帖内大图!

    您需要 登录 才可以下载或查看,没有账号?立即注册

    ×
    C++模版编程实现Haskell的函数模式匹配特性[图]:
    大神 Bartosz Milewski 在2009年写了一篇文章《What Does Haskell Have to Do with C++?》,使用C++实现Haskell函数式编程语言的一些特性。【传送门在文末】
    其中有这样一段例子:
    // code 1
    1.template<int n>class fact {
    2.public:
    3.     staticconstint value = n * fact<n -1>::value;
    4.};
    5.
    6.template<>class fact<0>{// specialization for n = 0
    7.public:
    8.     staticconstint value =1;
    9.};
    注:原文中使用的是struct关键字,这里改为class并加上了public
    我猜,你没看懂。没关系,我们先跳过上面这一段有着【令人恐怖的语法】的C++模版代码。
    上面的例子想干嘛呢?其实它只是想计算n的阶乘。

    C++模版编程实现Haskell的函数模式匹配特性[图]

    C++模版编程实现Haskell的函数模式匹配特性[图]
    如果你在C语言里面学过递归,应该知道下面这段计算阶乘的递归函数
    // 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 循环计算阶乘
    int p =1;
    for(int i=n; i >=1; i--)
    p *= i;
    return p;
    }
    那么,第一段代码(code1)与第二段代码(code2)的区别在哪里呢?
    区别在于,code1是在编译时(由编译器)计算的,code2是在运行时(就是代码运行的时候)计算的。
    现在来解释一下code1 (部分根据Bartosz Milewski文中的说法)
    // code 1
    /* 第1行代码声明了一个类模版 fact。
    这个模版接受一个“非类型参数”n,
    n是整数。
    */
    1.template<int n>class fact {
    2.public:
    /* 第3行代码声明了一个静态整型常量
    成员 value。而 value 的值是使用
    递归模版表示的
    */
    3.     staticconstint value = n * fact<n -1>::value;
    4.};
    5.
    /* 第6行代码是“特化”类模版fact,
    也就是显式地给出某种类型参数的
    类模板的一个实例的代码,而非由
    编译器生成。
    在这里,是给出了参数n为0时模板
    fact的代码。这样,编译器不会再
    根据类模版fact生成n=0时的代码
    关于模版特化,详见文末链接
    */
    6.template<>class fact<0>{// specialization for n = 0
    7.public:
    8.    static const int value = 1;
    9. };
    /* 根据C++规范,模版特化的代码必须
    放到模版声明之后。
    因此上面的代码看上去好像先处理了
    由n阶到n-1阶的降阶问题,然后再给
    出了0阶的解答
    这可不像code2。code2中有if/else,
    因此可以把降阶代码与0阶解答代码调
    换先后次序(当然if条件得改)。
    */
    那么这个用模版计算阶乘的代码(类?)该怎么用呢?如下:
    cout <<"Factorial of 0 = "<< fact<0>::value << endl;
    其中,C++编译器会为“fact<0>::value”这个调用匹配最合适的模版代码,也就是code1中的第6-9行代码。
    如果用非零参数调用呢?
    cout <<"Factorial of 8 = "<< fact<8>::value << endl;
    其中,C++编译器会为“fact<8>::value”这个调用匹配code1中的第1-4行代码。
    前面blahblhaaaaaaaaaaaah讲了一大堆,其实都不是正经事儿。
    正经是下面的Haskell代码:
    //code 4
    1. fact 0=1
    2. fact n = n * fact (n -1)
    上面两行代码定义了函数fact。fact是函数名,fact的后面、等号的前面是函数的参数。等号后面是函数体,函数体的计算结果就是fact函数的返回值。
    当程序员调用【fact 8】的时候(参数是8,因为Haskell函数调用一般不像C++那样给参数加括号),Haskell会将之匹配到上面代码的第2行。谁动了我的奶酪读书笔记摘抄好词好句及感悟赏析,这种参数匹配,是Haskell特有的函数声明与调用方式。
    所以前面的code1中C++模版代码,就是在模仿 code4 中的Haskell代码。
    下面给出一个完整的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)
    上面的代码输出结果是:
    8!  = 40320
    88! =185482642257398439114796845645546284380220968949399346684421580986889562184028199319100141244804501828416633516851200000000000000000000
    Haskell对C++说:我能算88!,你行吗?
    C++说:你欺负人!

    百姓地盘、草根平台!(点击修改为自己的签名)客服QQ:139725796
    • 打卡等级:即来则安
    • 打卡总天数:28
    • 打卡月天数:0
    • 打卡总奖励:1687
    • 最近打卡:2026-05-27 22:10:38
         
    年轻就是资本 发表于 2018-7-19 15:06 | 显示全部楼层 来自 中国–湖北–武汉 电信
    百姓地盘、草根平台!(点击修改为自己的签名)客服QQ:139725796
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    

    Archiver|手机版|小黑屋|认证|简介|联系我们|赤脚网[临沮网] ( 鄂ICP备18015422号|42052502000021 )

    GMT+8, 2026-6-17 19:13

    Powered by Discuz! X3.5

    © 2001-2026 Discuz! Team.

    网站内容仅代表网友个人观点,非本站认同之观点!删帖请用删帖卡,或在申请版块发帖申请,或联系【 bbs@yalj.net 】我们会尽快处理。
    声明:严禁任何人以任何形式在本站发表与中华人民共和国法律相抵触的言论!
    技术管理:远安坤哥    主办单位:远安县临沮网信息管理中心
                       
    快速回复 返回顶部 返回列表