免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 54244 | 回复: 7

发现ocaml这个语言也很不错 [复制链接]

论坛徽章:
1
天蝎座
日期:2013-12-06 18:23:58
发表于 2012-12-10 23:38 |显示全部楼层
ocaml.org  看到的第一眼就被吸引住了
  1. (* Binary tree with leaves carrying an integer. *)
  2. type tree = Leaf of int | Node of tree * tree

  3. let rec exists_leaf test tree =
  4.   match tree with
  5.   | Leaf v -> test v
  6.   | Node (left, right) ->
  7.       exists_leaf test left
  8.       || exists_leaf test right

  9. let has_even_leaf tree =
  10.   exists_leaf (fun n -> n mod 2 = 0) tree
复制代码

论坛徽章:
1
IT运维版块每日发帖之星
日期:2015-12-20 06:20:00
发表于 2013-12-06 17:49 |显示全部楼层
版主有oCaml的中文资料吗?

论坛徽章:
1
天蝎座
日期:2013-12-06 18:23:58
发表于 2013-12-06 18:23 |显示全部楼层
回复 2# goingstudy


    这些东西就看英文吧,中文的除了自己的笔记也不会有啥了

论坛徽章:
2
亥猪
日期:2014-03-19 16:36:35午马
日期:2014-11-23 23:48:46
发表于 2013-12-08 23:04 |显示全部楼层
ml部分很好,o部分就很怪胎,总之结合的很怪异。

论坛徽章:
1
IT运维版块每日发帖之星
日期:2015-12-20 06:20:00
发表于 2013-12-10 09:24 |显示全部楼层
回复 1# crazyhadoop

初学ocaml,请教点问题
  1. let rec rev accum = function
  2.     h :: t -> rev (h :: accum) t
  3. | [] -> accum

  4. let rec rev_map f accum = function
  5.     h :: t -> rev_map f ( f h :: accum) t
  6. | [] -> accum

  7. let map f l = rev [] (rev_map f [] l)
复制代码
这是一个对list 进行map操作的尾递归,版主能给讲讲吗,看了老长时间没看懂。
还有就是, 函数的参数是可以省略吗, 如上面的rev , 用let 写的时候有一个参数,下面递归调用时有两个参数

希望版主能介绍点经验

论坛徽章:
7
巳蛇
日期:2014-04-10 08:54:57白羊座
日期:2014-04-22 20:06:262015年亚洲杯之沙特阿拉伯
日期:2015-02-10 14:18:532015年辞旧岁徽章
日期:2015-03-03 16:54:152015亚冠之吉达阿赫利
日期:2015-06-02 11:34:112015亚冠之武里南联
日期:2015-06-24 12:13:082015亚冠之阿尔纳斯尔
日期:2015-08-03 09:08:25
发表于 2013-12-10 11:32 |显示全部楼层
goingstudy 发表于 2013-12-10 09:24
初学ocaml,请教点问题

1.   let rec rev accum = function
2.       h :: t -> rev (h :: accum) t
3.   | [] -> accum

4.   let rec rev_map f accum = function
5.       h :: t -> rev_map f ( f h :: accum) t
6.   | [] -> accum

7.   let map f l = rev [] (rev_map f [] l)

复制代码
这是一个对list 进行map操作的尾递归,版主能给讲讲吗,看了老长时间没看懂。
还有就是, 函数的参数是可以省略吗, 如上面的rev , 用let 写的时候有一个参数,下面递归调用时有两个参数

希望版主能介绍点经验

我就多管闲事一次吧。
其实你如果真正理解什么是函数式编程的话,上面的代码很容易理解。首先回答你的第二个问题,本质上函数是编程里的函数你可以认为它们都只接收一个参数,只不过这个接收一个参数的函数可以返回另一个接收一个参数的函数,从而看上去好像可以接受多个参数,不管实现上是怎样的,你都可以认为多参数形式的函数定义只不过是单参数形式函数定义的一种语法糖。接着,要真正让你理解你提的第二个问题,你还得(真正意义上)懂匿名函数。我这里都提到了匿名函数,你肯定已经知道匿名函数就是没有名字的函数,刚才说了,函数式编程里一个函数可以返回另一个函数,事实上我们这里定义的 rev 以及 rev_map 都是(在形式上)定义为(分别)接收一个(两个)参数,并返回一个接收一个参数的(匿名)函数(这由右边的function来定义,参数个数可以从 function 和 -> 之间的参数个数数出来),这等同于 rev (rev_map) 是一个接收两个(三个)参数并返回一个非函数值的函数(当然也等同于一个接收0个(一个)参数并返回接收两个参数的函数),所以在let里虽然是只写了一个参数,但是,事实上调用的时候可以(而且一般会)使用两个参数(除非你想返回一个函数,而不是值),也就是
  1. let rec rev accum = function
  2.       h :: t -> rev (h :: accum) t
  3.     | [] -> accum
复制代码
等同于
  1. let rec rev accum list = match list with
  2.     h :: t -> rev (h :: accum) t
  3.   | [] -> accum
复制代码
(我对Haskell更熟一点,不过前几天刚看了一两段Ocaml代码,希望上面的改写没有任何问题)
回到你的第一个问题,为了方便叙述,我在上面的引用中给代码加了编号(后面称行,不过我有意没有给空行编号),第一行的意思是定义一个递归函数,rev,它接收一个参数 accum 并返回一个匿名函数,第二行的意思,这个匿名函数接收一个参数,但是,如果这个参数是一个非空列表的话,就把这个列表的首元素和h绑定,剩余的(是一个可能为空的列表)部分和t绑定,然后把 h 加到 accum 这个列表之前,并作为第一个参数,然后把t作为第二个参数递归调用rev,第三行的意思是如果匿名函数的参数是一个空列表的话就直接返回accum,所以这三行定义的rev函数的最终意思是它接收一个列表accum,和另一个列表(暂叫做xs),它把xs倒置过来,并加到accum前面,所以如果 accum 是[1,2,3], xs 是 [4,5,6],那么 rev accum xs 的结果就是[6,5,4,1,2,3]。第4,5,6行跟第1,2,3行意思差不多,只是rev_map还接收一个参数f,然后f本身是一个函数(是的,在函数式编程里把一个函数作为另一个函数的函数或者返回值都很普遍),然后递归的时候话把f作用到h上。最后一行就是这两个函数的应用,我就不详讲了。
要理解函数代码的关键是要(真正)理解函数式编程的基本概念。

论坛徽章:
6
数据库技术版块每日发帖之星
日期:2015-11-27 06:20:00程序设计版块每日发帖之星
日期:2015-12-01 06:20:00每日论坛发贴之星
日期:2015-12-01 06:20:0015-16赛季CBA联赛之佛山
日期:2017-03-26 23:38:0315-16赛季CBA联赛之江苏
日期:2017-07-17 10:08:4415-16赛季CBA联赛之北京
日期:2018-03-04 17:01:50
发表于 2014-07-29 14:49 |显示全部楼层
ocaml这个语言是很不错

论坛徽章:
1
数据库技术版块每日发帖之星
日期:2015-09-25 06:20:00
发表于 2015-09-22 16:29 |显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP