Learning F#

https://swlaschin.gitbooks.io/fsharpforfunandprofit/content/learning-fsharp/

函数式语言与标准的命令式语言有很大的不同,最初可能会很难掌握。本页提供了一些关于如何有效学习F#的提示。

作为初学者来学习 F#

如果你有C#和Java等语言的经验,你可能已经发现你可以很好地理解用其他类似语言编写的源代码,即使你不熟悉这些关键词或库。这是因为所有的命令式语言都使用相同的思维方式,一种语言的经验可以很容易地转移到另一种语言。

如果你像许多人一样,你学习一种新的编程语言的标准方法是找出如何实现你已经熟悉的概念。你可能会问 "我如何分配一个变量?"或 "我如何做一个循环?",有了这些答案,你就能很快做一些基本的编程。

在学习F#时,你不应该试图把你以前的命令式概念带过来。在纯函数式语言中,没有变量,没有循环,也没有对象!

是的,F#是一种混合模式语言,确实允许使用这样的方式来编程。但如果你以初学者的心态开始,你会学得更快。

改变你的思维方式

重要的是要明白,函数式编程不仅仅是一种风格上的差异;它是一种完全不同的编程思维方式,就像真正的面向对象编程(比如Smalltalk)也是一种不同于传统的命令式语言(比如C)的思维方式。

F#确实允许非函数式的风格,而使用你已经熟悉的编程方式是非常诱人的。你可以只用非函数式的方式来使用F#,而不真正改变你的思维方式,但是这样你就完全没有意识到你错过了什么。要想最大限度地利用F#,并在一般情况下流畅自如地使用函数式编程,关键是你要从函数式的方式上思考问题,而不是命令式的。

到目前为止,你能做的最重要的事情就是花时间和精力去准确理解F#的工作原理,尤其是涉及函数和类型系统的核心概念。因此,请阅读和重读 "从函数式的角度思考 " 和 " 理解F#的类型系统 " 系列,运行和尝试一下这些例子,在你尝试开始进行认真的编码之前,并且适应这些思考方式。如果你不理解函数和类型是如何工作的,那么你将很难有写出有意义的代码。(TODO:添加链接)

该做的和不该做的

这里有一份该做和不该做的清单,将帮助你进行函数式的思考。这些一开始会很难,但就像学习一门外语一样,你必须潜心学习,强迫自己像 native speaker 一样使用这个语言。

  • 作为一个初学者,根本就不要使用mutable关键字。编写复杂的函数而不使用可变状态的辅助,将真正迫使你理解函数式范式。

  • 不要使用for循环或if-then-else。要使用模式匹配来判断布尔(逻辑)值和遍历列表。

  • 不要使用 “点标记”。与其 “点入” 对象,不如尝试对所有对象使用函数。也就是说,写 String.length "hello" 而不是 "hello".Length。这看起来像是额外的工作,但在使用管道和高阶函数(如 List.map)时,这种工作方式是必不可少的。也不要编写自己的方法!有关详细信息,请参阅此帖子。(TODO:添加链接)

  • 作为上一条的衍生,不要创建类或者使用。仅使用纯 F# 类型,例如元组(Tuple)、记录(Record)和联合(Union)。

  • 不要使用调试器(Debugger)。如果你依赖调试器来发现和修正不正确的代码,你可能会很受打击。在F#中,你基本上不会走到这一步,因为编译器在很多方面都要严格得多。当然,也没有任何工具可以 "调试 "编译器并逐步完成其处理过程。调试编译器错误的最好工具是你的大脑,而F#迫使你使用它!

另一方面(要这么做):

  • 创建大量的 "little types",特别是联合类型(union)。它们是轻量级的,而且易于使用,它们的使用将有助于构建和描述你的领域模型并确保正确性。

  • 一定要了解列表list和序列seq类型及其相关的库模块。像 List.fold List.map这样的函数非常强大。只要你了解了如何使用它们,你就会很容易地理解一般的高阶函数。

  • 一旦你理解了集合collection 模块,那就尽量避免递归。递归可能很容易出错,而且很难确保它是正确的尾部递归。当你使用List.fold时,你永远不可能有这个问题。

  • 尽可能多地使用管道pipe (|>)和组合composition (>>)。这种方式比嵌套的函数调用,如f(g(x)),更符合习惯。

  • 做到了解partial application的工作原理,并尝试适应point-free (tacit) 风格。

  • 做到循序渐进地开发代码(增量式的开发),使用交互式方式测试代码片段。如果你盲目地创建大量的代码,然后试图一次性编译,你可能会出现许多令人痛苦的、难以调试的编译错误。

Troubleshooting

初学者会犯一些极为常见的错误,如果你为让你的代码编译而感到沮丧,请阅读 "F#故障排除 "页面。

Last updated