免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
123下一页
最近访问板块 发新帖
查看: 11681 | 回复: 27
打印 上一主题 下一主题

haskell 初学问疑 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-03-26 20:24 |只看该作者 |倒序浏览

  1. f x =
  2.   case x of
  3.     1->-1
  4.     2->2
  5.     _->0

  6. ERROR:
  7. Syntax error in case expression (unexpected symbol "->-")
复制代码

1.以上代码出错可否判断 haskell 的运算符匹配是贪婪型的 ?

2.haskell 中大量运用递归,是否对程序的效率有影响 ?

3.python 中的 generator 是不是有 lazy 的影子 ?

[ 本帖最后由 izhier 于 2009-3-26 23:03 编辑 ]

论坛徽章:
0
2 [报告]
发表于 2009-03-27 00:11 |只看该作者
楼主不如先介绍一下 Python 中的 generator? 懂 lazy 影子的人不一定懂 Python 啊。


ps: 如果楼主对 Python 比较熟悉,介绍一下 Python 中的函式支持也不错。

[ 本帖最后由 win_hate 于 2009-3-27 00:12 编辑 ]

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
3 [报告]
发表于 2009-03-27 00:14 |只看该作者
Haskell 可以任意制造新的运算符,
因此在做词法分析时,依赖空格来分隔 token 应该可以理解。
其实说来也怪,我学别的语言的时候,都会去学习它的词法分析过程,
但是学 Haskell 从来没关心过这个。

至于递归麽,递归有一种叫做尾递归,编译期可以优化成循环的,
不是尾递归的,也有一部分可以转化成尾递归,这个理论上编译期都可以做优化。
剩下那些不能优化的,递归的时候就会影响性能,尤其是栈的消耗,
不过栈有大小限制,超过大小就会出错。

至于 Python 的生成器么,绝对不是 lazy,因为它的语义就是那样,语义和实际的行为是吻合的。
而 Haskell 的 lazy 是指,语义和行为不吻合。
比如 [1..],它的语义是个无限列表,但是实际使用它的时候,比如 take 10 [1..],并没有真的产生这个无限列表。
再比如 readFile "1G.file",它的语义是把整个 1G 文件的内容都返回,
但是实际运行的时候,它并不会真的读 1G,也是需要多少就读多少。
这才是 lazy 的意思:语义承诺很多,但是实际做到刚好。

论坛徽章:
0
4 [报告]
发表于 2009-03-27 10:46 |只看该作者
原帖由 win_hate 于 2009-3-27 00:11 发表
楼主不如先介绍一下 Python 中的 generator? 懂 lazy 影子的人不一定懂 Python 啊。

虽然学习 python 不精,但愿抛砖引玉,如果有哪些不对,还望指正,改之

python generator:

在 python 中,generator function 是一个可以保存状态的函数,用 yield 指令(不是 return )返回一个值,保存当前整个函数执行状态,等待下一次调用,
当需要该函数返回值时,该 generator function 恢复整个函数执行状态,直至再次遇到 yield 指令,再次返回一个值,再次保存当前函数执行状态,再次等待。
如此循环往复,直至函数末尾,发生 StopIteration 异常。

generator 利用 next() method 来获取 generator 的下一个返回值。这样,generator在需要返回中间值时,
调用 next() method,获取 generator 的下一个返回值,保存当前函数状态,等待下一次的返回要求。

先看一个例子吧:

  1. >>> def num_gen(n):
  2. ...     for i in range(n):
  3. ...             yield i*2
  4. ...
  5. >>> g = num_gen(6)
  6. >>> g
  7. <generator object at 0xb806f76c>
  8. >>> g.next()
  9. 0
  10. >>> g.next()
  11. 2
  12. >>> g.next()
  13. 4
  14. >>> g.next()
  15. 6
  16. >>> g.next()
  17. 8
  18. >>> g.next()
  19. 10
  20. >>> g.next()
  21. Traceback (most recent call last):
  22.   File "<stdin>", line 1, in <module>
  23. StopIteration
复制代码


函数里只要有了yield,这个函数就会被编译成一个 generator 函数,以上定义的 num_gen 函数就是一个 generator function,
num_gen(6) 返回一个 generator object,赋值于 g, 当 g 对象调用 next() 时,返回该 generator 的下一个值

!也就是说:当我们需要 generator 的返回值时,调用 next() 就可以了,
只有需要时,才会调用函数,取得返回值

好像有一点 lazy

论坛徽章:
0
5 [报告]
发表于 2009-03-27 10:53 |只看该作者
原帖由 flw 于 2009-3-27 00:14 发表
而 Haskell 的 lazy 是指,语义和行为不吻合。
比如 [1..],它的语义是个无限列表,但是实际使用它的时候,比如 take 10 [1..],并没有真的产生这个无限列表。


python generator 也可以由此功能呀!

  1. >>> def gen():
  2. ...     n = 0
  3. ...     while True:
  4. ...             yield n
  5. ...             n += 1
  6. ...
  7. >>> g = gen()
  8. >>> g.next()
  9. 0
  10. >>> g.next()
  11. 1
  12. >>> g.next()
  13. 2
  14. ...
复制代码

论坛徽章:
95
程序设计版块每日发帖之星
日期:2015-09-05 06:20:00程序设计版块每日发帖之星
日期:2015-09-17 06:20:00程序设计版块每日发帖之星
日期:2015-09-18 06:20:002015亚冠之阿尔艾因
日期:2015-09-18 10:35:08月度论坛发贴之星
日期:2015-09-30 22:25:002015亚冠之阿尔沙巴布
日期:2015-10-03 08:57:39程序设计版块每日发帖之星
日期:2015-10-05 06:20:00每日论坛发贴之星
日期:2015-10-05 06:20:002015年亚冠纪念徽章
日期:2015-10-06 10:06:482015亚冠之塔什干棉农
日期:2015-10-19 19:43:35程序设计版块每日发帖之星
日期:2015-10-21 06:20:00每日论坛发贴之星
日期:2015-09-14 06:20:00
6 [报告]
发表于 2009-03-27 10:56 |只看该作者
原帖由 izhier 于 2009-3-26 20:24 发表

f x =
  case x of
    1->-1
    2->2
    _->0

ERROR:
Syntax error in case expression (unexpected symbol "->-")

1.以上代码出错可否判断 haskell 的运算符匹配是贪婪型的 ?

可以,而且它本来就是。

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
7 [报告]
发表于 2009-03-27 10:57 |只看该作者
原帖由 izhier 于 2009-3-27 10:53 发表


python generator 也可以由此功能呀!

>>> def gen():
...     n = 0
...     while True:
...             yield n
...             n += 1
...
>>> g = gen()
>>> g.next()
0
>>> g.next()
...

yield 的语义,你真的明白了吗?

yield 是一个流程控制语句,它的语义明明确确,除了保存函数调用栈之外,我想不出它和 return 有什么分别。

[ 本帖最后由 flw 于 2009-3-27 10:59 编辑 ]

论坛徽章:
0
8 [报告]
发表于 2009-03-27 10:58 |只看该作者
原帖由 flw 于 2009-3-27 00:14 发表
再比如 readFile "1G.file",它的语义是把整个 1G 文件的内容都返回,
但是实际运行的时候,它并不会真的读 1G,也是需要多少就读多少。
这才是 lazy 的意思:语义承诺很多,但是实际做到刚好。


python 中读文件时:

  1. f = open("file.txt", 'r')
  2. for each_line in f:
  3.     do_something
复制代码

以上也是一句一句的读文件,并不是一次性的把文件读完呀

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
9 [报告]
发表于 2009-03-27 11:00 |只看该作者
原帖由 izhier 于 2009-3-27 10:58 发表

python 中读文件时:

f = open("file.txt", 'r')
for each_line in f:
    do_something

以上也是一句一句的读文件,并不是一次性的把文件读完呀

注意语义。
f 是一个文件句柄,
而 readFile 返回的是一个字符串,且从语义上讲,这个字符串就是文件的所有内容。

我再强调一次,一定要搞清楚语义。
Python 的确可以一行一行的读文件,这很好。大多数语言都支持这个功能。

论坛徽章:
0
10 [报告]
发表于 2009-03-27 11:03 |只看该作者
原帖由 flw 于 2009-3-27 10:57 发表
yield 的语义,你真的明白了吗?

不是太明白你说的语义是什么?

generator 不是只有在需要返回值时,才再次运行函数吗?
难道这没有 lazy 吗?
是不是我对 lazy 的概念有点不清呀?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP