携手创造,共同成长!这是我参与「日新方案 8 月更文挑战」的第25天,点击查看活动概况

Swift基础语法文章汇总

  1. 函数式编程的知道
  2. 高阶函数
  3. 函数柯里化
  4. 函子/适用函子
  5. 单子

1. 知道

函数式编程( Funtional Programming ,简称FP)是一种编程范式,也便是怎么编写程序的方法论。

首要思维: 把核算进程尽量分解成一系列可复用函数的调用。

首要特征: 函数是“榜首等公民。函数与其他数据类型相同的地位,能够赋值给其他变量,也能够作为函数参数、函数回来值。

通俗的说函数式编程便是将整个的操作进程拆分成不同的函数,以函数为单位依次进行调用

常见概念:

  • Higher-Order Function(高阶函数)
  • Function Currying(函数柯里化)
  • Functor(函子)
  • Applicative Functor(适用函子)
  • Monad(单子)

2. 运用

函数式编程的简略运用

/*
 0、编程思维的知道
 两个数相加
 */
func test0() {
    /*
     1. 先传入参数v,将其作为一个函数的操作数
     2. 回来一个函数
     3. 该函数需求传入一个值,核算后回来两个值的和
     */
    let num = 1
    func add(_ v: Int) -> (Int) -> Int {
        return {
            $0 + v
        }
    }
    print("test0:",add(3)(num))
}

阐明:

  • 传统上对于多个核算进程需求经过不同的函数传参进行处理,上一个函数的成果作为下一个函数的参数,这样的可读性很差,并且写法上不行高雅。
  • 运用函数式编程将核算进程进程拆分,两次调用来实现
  • 这儿在调用add函数后再回来一个函数
  • 回来的函数用闭包表达式表明,操作时将传入的值$0+v
  • 因而先接纳一个参数,再接纳另一个参数(这便是拆分核算进程)
  • 将3+num的操作进行拆分,榜首次先传入3拿到一个函数,第2次再传入一个num,对3和num进行核算

3、 高阶函数

只要满足以下任一条件便是高阶函数:

  1. 承受一个或多个函数作为输入( map、filter、reduce等)
  2. 回来一个函数

代码:

func add(_ v: Int) -> (Int) -> Int { { $0 + v } }

阐明:

  • 这儿回来了一个函数,其实便是高阶函数
  • 因而在函数式编程中的函数都是高阶函数

4、 柯里化(Currying)

将一个承受多参数的函数变换为一系列只承受单个参数的函数的进程便是柯里化

函数式贬称就需求将多个操作分解成不同函数,以函数为单位进行调用。因而函数式编程就需求进行柯里化

4.1 柯里化知道

Swift基础语法(二十一)常见编程范式认识:函数式编程

Swift基础语法(二十一)常见编程范式认识:函数式编程

阐明:

  1. 首要传入一个函数fn
  2. 将该函数进行必定操作后进行回来。需求回来的值是一个函数(该函数为参数为B,回来值是一个(A) -> C的函数)
  3. 回来的这个函数传入的值是B类型的值,最终回来的是函数的参数为A类型的值
  4. 函数体为是调用fn(a,b)
  5. 因而这个函数将传入进来的函数fn的a+b的进程进行了拆分,别离回来两个函数,每个函数都带有一个参数。

4.2 柯里化的运用

Array、 Optional的map方法接纳的参数便是一个柯里化函数

Swift基础语法(二十一)常见编程范式认识:函数式编程

Swift基础语法(二十一)常见编程范式认识:函数式编程

阐明:

  1. 兼并函数,需求传入两个函数,回来一个函数
  2. 这儿具体的操作仍然是相同的,只是调用一下
  3. 创立>>>运算符用来兼并函数,因而add(3) >>> multiple(5)便是将这两个操作进行了兼并,并且赋给了fn,这儿的兼并其实便是f2(f1($))),也便是说里边的操作和传统写法相同。
  4. 之后调用fn(num)便是将这些操作全部进行了一遍
  5. 柯里化就能够将这些运算进行拆分

5、 函子

像Array、 Optional这样支撑map运算的类型,称为函子( Functor)。

代码:

/*
 3、函子:像Array、  Optional这样支撑map运算的类型,称为函子( Functor)
 */
func test3() {
    /*map知道
     回来一个数组,其中包含将给定闭包映射到序列元素上的成果
     - Parameter transform:一个映射闭包
        1. 这个闭包接纳数组元素作为它的参数
        2. 回来一个转化后的值,这个值的类型能够与参数相同,也能够不同
     - Returns:
        回来一个数组,数组元素为转化后数组的元素
    @inlinable public func map<T>(_ transform: (Element) throws -> T) rethrows -> [T]
     */
    /*
     数组:Array<Element>
     publicfuncmap<T>(_transform:(Element)->T)->Array<T>
     */
    let arr1 = [1,2,3]
    let arr2 = arr1.map { $0 * 2 }
    print("arr2:",arr2)
    /*
     可选项:Optional<Wrapped>
     publicfuncmap<U>(_transform:(Wrapped)->U)->Optional<U>
     */
    let a: Int? = 1
    let b: Int? = a.map { $0 * 3 }
    print("b:",b!)
}

阐明:

  1. 取出Type内部元素进行处理
  2. 处理后再包装到Type类型中回来

6、 适用函子

条件:

func pure<A>(_ value: A) -> F<A>
func <*><A, B>(fn: F<(A) -> B>, value: F<A>) -> F<B>
  • 榜首个函数条件

    • 随便给一个类型,都能用函子包装,并且泛型是这个类型
    • 传入类型为A的值
    • 回来一个对A类型的操作
  • 第二个函数条件

    • 传入两个参数,榜首个参数是F泛型一个函数,并且函数是经过A类型得到B类型,第二个参数是F泛型A。最终得到F泛型B
  • 操作是包装的,参数是包装的,回来也是包装的,便是适用函子

Swift基础语法(二十一)常见编程范式认识:函数式编程

代码:

/*
 4、适用函子
 */
//Optional的适用函子条件
func pure<A>(_ value: A) -> A? { value }//易理解
infix operator <*> : AdditionPrecedence
//传入可选项函数(A) -> B ,传入A? ,回来B?
//将A传入函数fn中,拿到的仍然是个可选项
func <*><A, B>(fn: ((A) -> B)?, value: A?) -> B? {
    guard let f = fn, let v = value else { return nil }
    return f(v)
}
//Array的适用函子条件
func pure<A>(_ value: A) -> [A] { [value] }//易理解
//传入数组元素为函数,传入数组元素为A,拿到数组元素为B
//取出fn和value的元素别离进行调用。回来成果放到一个数组中
func <*><A, B>(fn: [(A) -> B], value: [A]) -> [B] {
    var arr: [B] = []
    if fn.count == value.count {
        for i in fn.startIndex..<fn.endIndex {
            arr.append(fn[i](value[i]))
        }
    }
    return arr
}
//调用
func test4() {
    var value: Int? = 10
    var fn: ((Int) -> Int)? = { $0 * 2}
    // Optional(20)
    print(fn <*> value as Any)
    // [10]
    print(pure(10))
    var arr = [{ $0 * 2}, { $0 + 10 }, { $0 - 5 }] <*> [1, 2, 3]
    // [2, 12, -2]
    print(arr)
}

阐明:

  • Optional的适用函子
    • 榜首函数条件:传入一个数值,之后回来可选项
    • 第二个函数条件
      • 榜首个参数函数fn是一个包装函数的可选项,第二个参数是是可选项A,回来可选项B
      • 值绑定形式中,f为解包后的函数,v为解包后的值
      • 他们进行调用,调用后回来了一个值,是可选项
  • Array的适用函子
    • 寄存函数的数组,寄存A的数组,之后拿到寄存B的数组

7、 单子

代码:

func pure<A>(_ value: A) -> F<A>
func flatMap<A, B>(_ value: F<A>, _ fn: (A) -> F<B>) -> F<B>

阐明:

  • 函数一:传入一个值,回来改值的包装
  • 函数二:传入一个值A的包装,一个函数,函数是经过A得到B的包装,经过函数的核算最终回来B的包装

很显然, Array、 Optional也都是单子

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。