Kotlin(十七)函数式编程<1>

作者: zcwfeng | 来源:发表于2021-02-25 11:21 被阅读0次

    前言:函数式编程分为狭义和广义两个方面
    狭义函数式编程,有着非常严格的标准,只通过纯函数编程,不允许有副作用,所有的数据结构都是不可以改变的。

    广义的函数式编程,不强调的都是纯函数。常见的函数式的语言特性:

    • 函数是头等公民
    • 方便的闭包语法
    • 递归式的构造列表
    • 柯里化的函数
    • 惰性求值
    • 模式匹配
    • 尾递归优化
    • 强大的泛型能力,包括高阶类型(支持静态类型的函数式语言)
    • Typeclass
    • 类型推导。
      Kotlin 支持上面大部分特性。

    纯函数和引用透明性

    sealed class Format
    data class Print(val text: String) : Format()
    object Newline : Format()
    val string = listOf<Format>(Print("Hello"),
        Newline, Print("Kotlin"))
    fun unsafeInterpreter(str:List<Format>){
        str.forEach {
            when(it){
                is Print -> print(it.text)
                is Newline -> println()
            }
        }
    }
    

    unsafeInterpreter,引入了副作用

    1.缺乏可测试性。如果变更,添加不是print而是写数据库相关方法,如果测试的时候,就会麻烦。

    2.难易组合复用。内部混合了字符串格式转化逻辑,如果这里不是打印操作,而是数据库操作,就不能当做字符串转换功能使用。

    稍微改动一下,举个例子说明:

    fun stringInterpreter(str:List<Format>)
            = str.fold(""){fullText,s ->
        when(s){
            is Print -> fullText + s.text
            is Newline ->fullText + "\n"
        }
    }
    

    函数返回字符串结果,无论测试还是复用,都有所提升

    基本法则:引用透明性
    一个表达式在程序中,可以被它等价的值替换,而不影响结果

    一个函数具备引用透明性,内部行为不会改变外部状态

    近似数学中的等式推理

    纯函数与局部可变性

    引用透明不是说不可变,而是局部可变,而整体调用外面是个黑盒,结果是一致的。

    fun foo(x:Int):Int{
        var y = 0
        y = y + x
        return y
    }
    

    foo具备纯函数f(x)->y.

    副作用,在一定的抽象概念,并不绝对没有副作用,即使纯函数,也会使用内存,占用cpu

    纯函数具有局限性random随机函数结果不一致都是不同的,不是纯函数

    代换模型与惰性求值

    错误的例子StackOverflowError 死循环

    fun f1(x:Int,y:Int) = x
    fun f2(x:Int):Int = f2(x)
    
    1. 应用序和正则序

    kotlin中会先对f2(2) 进行求值,所以会导致死循环
    然而如Hashell这种老的纯函数语言,会先调用f1(1,y),因为用不到y所以不会对f2(2)求值

    1. 惰性求值
      模拟一下
      比如针对println,他是一个非纯函数,改造让他"lazy"
    fun lazyPrintln(msg:String) = { println(msg)}
    

    当我们执行 lazyPrintln("I am IO operation"),
    他仅仅返回一个可执行的println是惰性的,也是可以替代的。

    相关文章

      网友评论

        本文标题:Kotlin(十七)函数式编程<1>

        本文链接:https://www.haomeiwen.com/subject/pbjhxltx.html