c#函数式编程 Functional Programming in C# [4]

1.4 高阶函数

  现在你已经了解了什么是FP,我们也回顾了语言的功能特性,现在是时候开始探索一些具体的功能技术了。我们将从函数作为第一公民的最重要的好处开始:它使你有能力定义高阶函数(HOFs)。
  HOFs是将其他函数作为输入或将一个函数作为输出返回的函数,或者两者都是。我假定你已经在某种程度上使用过HOFs,比如用LINQ。在本书中,我们会经常使用HOFs,所以本节应作为复习,并可能介绍一些你可能不太熟悉的HOFs用例。HOFs很有趣,本节中的大多数例子都可以在REPL中运行。请确保你在这一过程中尝试一些自己的变化。

1.4.1 依赖于其他函数的函数

  一些 HOF 将其他功能作为参数并调用它们以完成其工作,有点像一家公司可能会将其某些工作分包给另一家公司。您已经在本章前面看到了一些此类 HOF 的示例:Sort(List 上的实例方法)和 Where(IEnumerable 上的扩展方法)。
  List.Sort,当与Comparison委托一起调用时,是一个说:"好吧,我自己排序,只要你告诉我如何比较我包含的任何两个元素。"Sort做排序的工作,但调用者可以决定使用什么逻辑进行比较。
  同样地,Where做的是过滤的工作,调用者决定用什么逻辑来判断一个元素是否应该被包含。你可以用图形来表示Where的类型,如图1.4所示。
在这里插入图片描述
  让我们看一下 Where 的理想化实现

清单1.10 Where:一个典型的HOF,反复应用给定的谓词。

publicstatic IEnumerable<T> Where<T> (this IEnumerable<T> ts, Func<T, bool> predicate)
{
	foreach (T t in ts)
		if (predicate(t))
			yield return t;
}

  Where方法负责排序逻辑,调用者提供predicate,这是IEnumerable应该被过滤的标准。
  正如你所看到的,HOF可以在逻辑不容易分离的情况下帮助实现关注点的分离。Where和Sort是迭代应用的例子–HOF将对集合中的每个元素重复应用给定的函数。
  一个非常粗略的方法是,你传递的参数是一个函数,其代码最终将在HOF中的循环体中执行–这是你只传递静态数据所做不到的。一般的方案显示在图1.5中
在这里插入图片描述
  可选执行是HOF的另一个好办法。 当你想只在特定的条件下调用一个给定的函数时,这很有用,如图1.6所示。
在这里插入图片描述

  例如,设想有一个方法可以从缓存中查找一个元素。可以提供一个委托,并在缓存丢失的情况下被调用。

清单 1.11 可选调用给定函数的 HOF

class Cache < T > where T: class {
    public T Get(Guid id) => //...
    public T Get(Guid id, Func < T > onMiss) 
    	=> Get(id) ?? onMiss();
}

  onMiss中的逻辑可能涉及到一个昂贵的操作,如数据库调用,你不会希望这个操作被不必要地执行。
  前面的例子说明了将一个函数作为输入的HOF(通常被称为回调或延续),并使用它来执行一个任务或计算一个值。这也许是HOF最常见的模式,它有时被称为控制倒置:HOF的调用者通过提供一个函数来决定做什么,而被调用者通过调用给定的函数来决定何时做。
  让我们看看 HOF 派上用场的其他一些场景。

1.4.2 适配器功能

  有些HOF根本不应用给定的函数,而是返回一个新的函数,与作为参数的函数有某种联系。例如,假设你有一个执行整数除法的函数:

Func<int, int, int> divide = (x, y) => x / y;
divide(10, 2) // => 5

  你想改变参数的顺序,使除数排在前面。 这可以看作是一个更普遍的问题的一个特殊案例:改变参数的顺序。
  你可以写一个通用的HOF,通过调换参数的顺序来修改任何二进制函数。

static Func<T2, T1, R> SwapArgs<T1, T2, R>(this Func<T1, T2, R> f)
	=> (t2, t1) => f(t1, t2);

  从技术上讲,更正确的说法是 SwapArgs 返回一个新的函数,该函数以相反的顺序调用给定的函数的参数。但从直观的角度看,我发现认为我得到的是原始函数的一个修改版本更容易。
  现在你可以通过应用SwapArgs来修改原来的除法函数:

var divideBy = divide.SwapArgs();
divideBy(2, 10) // => 5

  在玩这种HOF的时候,我想到了一个有趣的想法,那就是函数并不是固定不变的:如果你不喜欢一个函数的接口,你可以通过另一个函数来调用它,这个函数提供了一个更适合你需要的接口。这就是为什么我把这些函数称为适配器。

1.4.3 创建其他函数的函数

  有时你写的函数的主要目的是创建其他函数–你可以把它们看作是函数工厂。 下面的例子使用一个lambda来过滤一个数字序列,只保留能被2整除的数字:

var range = Enumerable.Range(1, 20);
range.Where(i => i % 2 == 0)
// => [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]

  如果你想要更普遍的东西,比如能够过滤被任何数字n整除的数字,会怎么样?你可以定义一个函数,接收n并产生一个合适的谓词,来评估任何给定的数字是否能被n整除:

Func<int, bool> isMod(int n) => i => i % n == 0;

  我们以前没有看过这样的HOF:它接收一些静态数据并返回一个函数。让我们看看你如何使用它:

using static System.Linq.Enumerable;
Range(1, 20).Where(isMod(2)) // => [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
Range(1, 20).Where(isMod(3)) // => [3, 6, 9, 12, 15, 18]

  请注意,你不仅在通用性方面得到了提高,而且在可读性方面也得到了提高 在这个例子中,你使用isMod HOF来产生一个函数,然后你把它作为输入送给另一个HOF,Where,如图1.7所示

在这里插入图片描述
  你会在书中看到更多的HOF的用法。最终你会把它们看成是常规函数,而忘记了它们是高阶函数。现在让我们来看看它们如何在更接近日常开发的情况下使用。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Take advantage of the growing trend in functional programming. C# is the number-one language used by .NET developers and one of the most popular programming languages in the world. It has many built-in functional programming features, but most are complex and little understood. With the shift to functional programming increasing at a rapid pace, you need to know how to leverage your existing skills to take advantage of this trend. Functional Programming in C# leads you along a path that begins with the historic value of functional ideas. Inside, C# MVP and functional programming expert Oliver Sturm explains the details of relevant language features in C# and describes theory and practice of using functional techniques in C#, including currying, partial application, composition, memoization, and monads. Next, he provides practical and versatile examples, which combine approaches to solve problems in several different areas, including complex scenarios like concurrency and high-performance calculation frameworks as well as simpler use cases like Web Services and business logic implementation. Shows how C# developers can leverage their existing skills to take advantage of functional programming Uses very little math theory and instead focuses on providing solutions to real development problems with functional programming methods, unlike traditional functional programming titles Includes examples ranging from simple cases to more complex scenarios Let Functional Programming in C# show you how to get in front of the shift toward functional programming.
原版pdf Summary Functional Programming in C# teaches you to apply functional thinking to real-world problems using the C# language. The book, with its many practical examples, is written for proficient C# programmers with no prior FP experience. It will give you an awesome new perspective. Purchase of the print book includes a free eBook in PDF, Kindle, and ePub formats from Manning Publications. About the Technology Functional programming changes the way you think about code. For C# developers, FP techniques can greatly improve state management, concurrency, event handling, and long-term code maintenance. And C# offers the flexibility that allows you to benefit fully from the application of functional techniques. This book gives you the awesome power of a new perspective. About the Book Functional Programming in C# teaches you to apply functional thinking to real-world problems using the C# language. You'll start by learning the principles of functional programming and the language features that allow you to program functionally. As you explore the many practical examples, you'll learn the power of function composition, data flow programming, immutable data structures, and monadic composition with LINQ. What's Inside Write readable, team-friendly code Master async and data streams Radically improve error handling Event sourcing and other FP patterns About the Reader Written for proficient C# programmers with no prior FP experience. About the Author Enrico Buonanno studied computer science at Columbia University and has 15 years of experience as a developer, architect, and trainer. Table of Contents
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值