lesson3   First-Class Functions
lesson3 First-Class Functions

lesson3 First-Class Functions

函数式编程主要体现在,1.避免数据可变 2.把函数作为值使用,它可以作为参数传递,作为值返回,可以赋值给其他变量

函数式语言在函数编程实现,也能在其他编程方式实现他

函数闭包,在解决如果这个变量不是局部变量,也不是参数,要怎么使用这个变量

高阶函数经常是多态的,但两只不是相互必然的关系

调用闭包函数分为两个部分,一部分是这段函数的代码,另一部分是他的作用域

词法作用域:根据函数定义的环境找到值

动态作用域:根据调用栈的环境找到值(e.g 捕获异常)

ref类型 ml的data可变类型

x的reference不会改变只会改变reference里面的值,这点跟js不同

在js,a的reference就被重新指向了,ml则是改变reference里面的内容

callback,利用闭包,当回调被调用时,内部数据不需要体现在函数类型里面,callback实现者也不需要考虑会有什么类型的内部书数据

抽象数据类型,通过定义一个函数集合来实现,在一个闭包函数里面,实现这个函数集合,这个私有变量不会被外界访问,每次返回新的S,S的xs拿到的是insert过后的xs

datatype set = S of { insert : int -> set, member : int -> bool, size : unit -> int }
val empty_set =
    let
        fun make_set xs = (* xs is a "private field" in result *)
            let (* contains a "private method" in result *)
                fun contains i = List.exists (fn j => i=j) xs
            in
                S { insert = fn i => if contains i
                                     then make_set xs
                                     else make_set (i::xs),
                    member = contains,
                    size   = fn () => length xs
                  }
             end
    in
          make_set []
    end
fun use_sets () =
    let val S s1 = empty_set
        val S s2 = (#insert s1) 34
        val S s3 = (#insert s2) 34
        val S s4 = #insert s3 19
    in
        if (#member s4) 42
        then 99
        else if (#member s4) 19
        then 17 + (#size s3) ()
        else 0
end

没有闭包要怎么实现闭包:

  • 在Java中,我们可以实现一个内部class,内部class的method拿到需要闭包的值,闭包的私有数据需要是final不可变类型
  • 在C中,我们虽然可以传递函数,但是函数是不可以在函数内部定义,函数必须在定义在最前面,因为不存在非局部变量(不是参数和局部变量),那参数就需要逐层传递,不能利用内部嵌套函数,获得非局部变量,需要动态去传这个env值(上下文)

而对于有闭包的情况,ml可以不去传递这个env,这个值在它定义的时候已经被绑定

闭包好处在于,可以将map分离,map的制定者知道怎么去遍历递归数据,map的使用者知道怎么处理数据,而像C版本的实现当中,map的制定者就必须将env传递,而这个env对于制定者来说是不必要,但是没有这个env,使用者就无法去拿到这个数据,因为这个函数的调用是在制定者当中的

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注