[fp] lich 问你几个fp的问题
simohayha
2007-06-08
haskell里面是不是所有的函数都是lambda实现的?不然为什么
:t 操作符所返回的都是 lambda的表示,也就是说都是用lambda解释的. 呵呵,最好讲下haskell里的type.和java或c里面的不同. 还有在scheme中 ((lambda x (+ x 1))2) 要改成 ((lambda x (+ (car x) 1))2)这样的 解释下原因 我知道是把2当成(2)来处理了,我想问这是什么原因. |
|
Lich_Ray
2007-06-08
是。只是语法上不太像。也可以说不是,因为那是lambda的"1.5版"(我的“术语”,Scheme中的是1.0版,学名“一阶lambda演算”)——Curry化算子。Curry化算子认为,一切都是函数(包括普通数据),但如果这个数据的产生式中每一项都是严格的(比如 num = 4 + 3, 3、4都是可以直接推导而不需要进行惰性化的),那么这个数据可以免除其作为函数的义务。对于产生式中有需要推导的数据,Haskell仍将其表示为普通数据(因为类型可以直接推导来确定)。
fact 0 = 1 fact n = n * fact (n-1) -- 这是函数,要推导 num = 5 + fact 4 -- 这个是事实上是函数,但类型上看不出来 另外,之所以haskell中的函数全是lambda的表示,和它的类型系统也有关系。前面说了,Haskell中对函数的理解已经超越了数学映射1.5倍,重点在于对参数列表的理解。数学映射和一阶lambda都认为参数是连续的、一次传递一批,就像Scheme中那样: (function arg1 arg2) 但Curry化算子认为参数是不连续的、可以分段传递(前提是个数事先固定),每当传递结束而参数不够是,自动转换为一个期待余下参数的函数。这就意味着,如果用Scheme的语法来说明Curry化算子就成了这样: ((+ 1) 2) ;调用一个固定参数个数为两个的函数 这句代码都将行得通! (map (+ 1) '(1 4 2 5 2)) 这对于Scheme来说是非常荒唐的(用宏另当别论),但对于Haskell这是基础: map (+1) [1, 4, 2, 5, 2] 所以,Haskell的类型系统中对于函数类型的表示才会是那么多个箭头:因为,只要需要推导,就有函数: Main> :t (+1) flip (+) 1 :: Num a => a -> a 看出来了吗?不连续的类型导出过程,和java/c等等等等最大的不同点。 至于Haskell类型系统的核心力量——静态多态类型推断,讲起来是在很麻烦。去看中文版的ML语言的书里讲的很详细。 下面那个Scheme的问题跟FP没关系,只是一个语法上的小问题。在Scheme的lambda表达式中,单个参数不带括号即把所有参数当作一个list来处理。不觉得这样写起来很有意思吗? |
|
simohayha
2007-06-08
引用 对于产生式中有需要推导的数据,Haskell仍将其表示为普通数据 这句怎么理解? |
|
Lich_Ray
2007-06-08
只要产生它的表达式中函数调用存在,那么就会被认作函数;但是它的类型只需要一步即可推导,所以Haskell它“看上去”是普通数据。
|
|
simohayha
2007-06-08
哦,理解了,谢谢你了.
|
|
cookoo
2007-06-13
引用 num = 5 + fact 4 -- 这个是事实上是函数,但类型上看不出来
Haskell是lazy的,所以这么说也不是没有道理,不过这个表达式在编译期肯定被固化成一个值了。 |
|
cookoo
2007-06-13
引用 最好讲下haskell里的type.和java或c里面的不同
C和Java的type都是primitive(int之类,没有对象接口)和自定义的结构体或类。 Haskell虽然不是OO语言,没有能保持状态的对象,但是有type class的概念。一个具体的type是type class的实例,将实现type class所定义的接口,比如Int是Num的实例。听上去比较古怪,再想一下就明白Haskell是为了把类型组织成一个层次结构。 |
|
simohayha
2007-06-13
昨天晚上把Programming In Haskell 里面那章讲type的,终于对type有点理解了,其实type的基础也就是Currying.
说到class,觉得PIH 里面的解释很好的说: 引用 a class is a collection of types that support certain overloaded operations called methods. |
|
cookoo
2007-06-13
我不觉得currying是fp的必要特征,Erlang就没有currying(故意不要的,认为那个容易混淆)。实际来说我觉得默认参数是更可读的方案。
|
|
simohayha
2007-06-13
cookoo 写道 引用 最好讲下haskell里的type.和java或c里面的不同
C和Java的type都是primitive(int之类,没有对象接口)和自定义的结构体或类。 Haskell虽然不是OO语言,没有能保持状态的对象,但是有type class的概念。一个具体的type是type class的实例,将实现type class所定义的接口,比如Int是Num的实例。听上去比较古怪,再想一下就明白Haskell是为了把类型组织成一个层次结构。 哦,这下明白了,嘿嘿,谢谢你了. 层次性结构,这也就是sicp里面一直推崇的设计方法. |
相关讨论
相关资源推荐
- otphp:与Google Authenticator兼容PHP OTP库
- Google:Android将尝试兼容iPhone程序
- android+wear+和iphone,Android Wear手表兼容iPhone:和苹果抢用户
- android wear 兼容问题,多款Android Wear手表不兼容iPhone 7
- android wear是否支持iphone,Android Wear兼容iPhone了 你让苹果表情何以堪
- android wear iphone7,多款 Android Wear 智能手表不兼容iPhone 7
- android wear iphone7,多款Android Wear手表不兼容苹果iPhone7
- Android的又一招聪明:兼容iPhone程序
- iphone和android照片传输,将照片从Android传输到iPhone的8种方法很容易
- H5中常见的 Android 和 iOS 兼容性问题