功能性Swift-咖喱

在使用Swift时,我在函数式编程环境中进行了越来越深入的研究。

在其他编程语言(例如Python或Haskell)中使用的许多技术可以迅速获得。

今天,我想向您介绍其中一种,称为currying。

Swift是一种出色的编程语言,它利用了函数式编程的优势。

函数式编程的主要好处之一是函数是高阶公民,这意味着迅速使用函数可以执行以下操作之一:

  • 将一个或多个函数作为参数
  • 返回一个函数作为参数

最近,我在函数程序员Curry中发现了一种众所周知的技术。

Currying用于将具有多个参数的函数分解为一系列包含参数的函数。

当您想提高代码的可读性和可重用性时,此技术变得非常有用。


该函数如下所示:

如您所见,咖喱是一个简单的功能。

它以一个函数作为参数( fn 首先返回一个函数 ,该函数采用传入参数的函数的第一个参数传递给curry(此处为A ):

  • (a: A) -> (B) -> C

然后,它返回一个函数 ,该函数采用传递给curry的函数的第二个参数(此处为B ):

  • (b: B) -> C

最后,使用参数AB调用作为参数传递的函数

  • fn (a,b)

值得注意的是,函数fn仅在最后一个参数传递给curried方法时才计算


在某些情况下,此方法可能有用,其中一种情况是您希望使现有方法更方便或可重复使用:

让我们采用以下日志方法:

使用两个参数调用它可能变得很乏味,使用curry我们可以使它可重用且更明确,而无需创建一个封装参数的新函数。

充分利用高阶函数的优势,我们可以分解logMessage并创建一个变量,该变量是一个将日志消息作为参数的函数,然后将其记录在调试级别。

另一个用途是利用诸如mapforEach等功能性方法。

让我们来看下面的例子:

如您所见,使用currying可以很容易地部分应用任何方法。


(Vincent Pradeilles在我当时所在的CocoaHeads展示了这种用咖喱粉的用例。)

如果您正在使用RxSwift或计划使用它,您可能想知道如何将使用completionBlock的异步代码迁移到一系列Observable。

重构所有代码库只是为了使其可观察而不是(completionBlock /成功和失败块)通常是不可行的。

使用curry和扩展,您几乎不需要代码即可实现。

Rx + FromAsync

第一个fromAsync方法将一个函数作为参数,该函数将completionBlock作为唯一参数。 该方法将处理转换为Observable的方法

其他两种方法的工作原理完全相同,只是它们使用curring分解参数并返回第一个fromAsync方法。

第一个用于转换具有一个参数和一个completionBlock的方法。

最后一个用于转换带有两个参数和一个completionBlock的方法。

从异步示例

Interesting Posts