F#之旅2 - 我有特别的学F#技巧

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了F#之旅2 - 我有特别的学F#技巧相关的知识,希望对你有一定的参考价值。

原文地址:https://swlaschin.gitbooks.io/fsharpforfunandprofit/content/learning-fsharp/

 

Learning F#
Functional programming languages need a different approach
学习F#
函数式编程语言需要不同的学习方法

Functional languages are very different from standard imperative languages, and can be quite tricky to get the hang of initially. This page offers some tips on how to learn F# effectively.
函数式编程语言和标准的命令式编程语言有很大的不同,很难上手。这里提供一些有效学习F#的小建议。

Approach learning F# as a beginner
If you have experience in languages such as C# and Java, you have probably found that you can get a pretty good understanding of source code written in other similar languages, even if you aren‘t familiar with the keywords or the libraries. This is because all imperative languages use the same way of thinking, and experience in one language can be easily transferred to another.
If you are like many people, your standard approach to learning a new programming language is to find out how to implement concepts you are already familiar with. You might ask "how do I assign a variable?" or "how do I do a loop?", and with these answers be able to do some basic programming quite quickly.
When learning F#, you should not try to bring your old imperative concepts with you. In a pure functional language there are no variables, there are no loops, and there are no objects!
Yes, F# is a hybrid language and does support these concepts. But you will learn much faster if you start with a beginners mind.
像初学者一样去学习F#
如果你有C#和Java之类的编程语言的经验,那你可能会发现,即使你不熟悉那些关键字或者库,也很容易就能很好的理解其它类似语言写的源码。这是因为所有的命令式编程语言使用相同的方式来考虑问题,你的某个语言的编程经验也能适用于另一个语言。
如果你像很多人一样,学习新语言的标准方法是去找出你已经熟悉的概念在新语言中的实现方法。那么,你可能会问:“怎样定义一个变量?”或者“我怎么写一个循环?”,接着你就能很快的学会完成一些基本的编程任务。
但你学F#时,你就不该还用老一套的编程关键概念了。在纯函数式的编程语言中,完全没有变量,也没有循环,没有对象!
当然,F#是一个混合型语言,也支持那些概念。但是,如果你抱着初学者的心态,你会学得更快。

Change the way you think
It is important to understand that functional programming is not just a stylistic difference; it is a completely different way of thinking about programming, in the way that truly object-oriented programming (in Smalltalk say) is also a different way of thinking from a traditional imperative language such as C.
F# does allow non-functional styles, and it is tempting to retain the habits you already are familiar with. You could just use F# in a non-functional way without really changing your mindset, and not realize what you are missing. To get the most out of F#, and to be fluent and comfortable with functional programming in general, it is critical that you think functionally, not imperatively.
By far the most important thing you can do is to take the time and effort to understand exactly how F# works, especially the core concepts involving functions and the type system. So please read and reread the series "thinking functionally" and "understanding F# types", play with the examples, and get comfortable with the ideas before you try to start doing serious coding. If you don’t understand how functions and types work, then you will have a hard time being productive.
改变你思考的方式
函数式编程不仅仅只有代码风格不同,理解这一点非常重要。它是一种完全不同的编程思考方式,就像真正的OOP编程也跟传统的C语言之类的命令式编程语言思考方式不同。
F#允许非函数式的编程风格,这吸引你保留你已经熟悉的那些编程习惯。你没有真正的改变你的心态,你就可以继续用不清真的方式来使用F#,然后也意识不到你所失去的。总的来说,为了发挥F#的最大功效,更流畅舒适的进行函数式编程,关键就是用函数式编程的思考方式来代替命令式。
目前为止,你能做的最重要的事情是花时间和精力去了解清楚,到底F#是如何工作的,特别是函数和类型系统这些核心概念。所以,在开始重要的编码工作之前,请反复阅读“函数式思维”和“理解F#的类型”这两个系列,玩一玩那些范例,去适应这些理念。如果你不理解函数和类型系统如何工作的,那么将难有成效。

Dos and Don‘ts
Here is a list of dos and don‘ts that will encourage you to think functionally. These will be hard at first, but just like learning a foreign language, you have to dive in and force yourself to speak like the locals.
Don‘t use the mutable keyword at all as a beginner. Coding complex functions without the crutch of mutable state will really force you to understand the functional paradigm.
Don‘t use for loops or if-then-else. Use pattern matching for testing booleans and recursing through lists.
Don‘t use "dot notation". Instead of "dotting into" objects, try to use functions for everything. That is, write String.length "hello" rather than "hello".Length. It might seem like extra work, but this way of working is essential when using pipes and higher order functions like List.map. And don‘t write your own methods either! See this post for details.
As a corollary, don‘t create classes. Use only the pure F# types such as tuples, records and unions.
Don‘t use the debugger. If you have relied on the debugger to find and fix incorrect code, you will get a nasty shock. In F#, you will probably not get that far, because the compiler is so much stricter in many ways. And of course, there is no tool to “debug” the compiler and step through its processing. The best tool for debugging compiler errors is your brain, and F# forces you to use it!
应该做的和不该做的:
下面是一个促进你感受函数式的列表。这开始会很难,但是就像去学习一门外语,你必须投身其中并且强迫自己像当地人一样说话。
作为初学者,不要使用mutable关键字。不依赖mutable的状态来写一些复杂的函数,能有效的迫使你理解函数式范式。
不要使用循环和条件判断。使用模式匹配来判断布尔值,通过列表来进行检索。
不要使用“.”,用函数来操作一切,替换掉用“.”来访问对象的成员。比如说,把 "hello".Length 改写成 String.length "hello" 。这看起来好像多此一举,但是在使用管道或者像List.map这样的高阶函数时,是需要这样做的。还有,不要自己写方法,具体原因看:http://fsharpforfunandprofit.com/posts/type-extensions/#downsides-of-methods
依此类推,不要定义类。仅仅使用内置的F#类型,例如tuples、records和unions。
不要使用调试器。如果你依赖调试器去寻找和修复有问题的代码,你可能会受点打击。在F#里面,因为编译器在很多方面都很严格,所以你可能会有点不太适应。当然,也没有工具用来调试编译器,并单步调试它的处理过程。F#强迫你使用你的脑子,这是处理编译错误最好的工具了。

On the other hand:
Do create lots of "little types", especially union types. They are lightweight and easy, and their use will help document your domain model and ensure correctness.
Do understand the list and seq types and their associated library modules. Functions like List.fold and List.map are very powerful. Once you understand how to use them, you will be well on your way to understanding higher order functions in general.
Once you understand the collection modules, try to avoid recursion. Recursion can be error prone, and it can be hard to make sure that it is properly tail-recursive. When you use List.fold, you can never have that problem.
Do use pipe (|>) and composition (>>) as much as you can. This style is much more idiomatic than nested function calls like f(g(x))
Do understand how partial application works, and try to become comfortable with point-free (tacit) style.
Do develop code incrementally, using the interactive window to test code fragments. If you blindly create lots of code and then try to compile it all at once, you may end up with many painful and hard-to-debug compilation errors.
另一方面:
多创建小类型,特别是union类型。他们简单又轻巧,将帮助你记录你的领域模型,并确保正确。
理解list和seq类型,以及它们的相关的库。像List.fold和List.map这样的函数非常强大。一旦你理解了它们,就就能很好的理解一般的高阶函数了。
一旦你理解了集合模块,尝试去避免递归。递归很容易出错,并且很难确保它是一个正确的尾递归。如果你使用List.fold,就不会有那样的问题了。
尽可能使用pipe(|>)和composition(>>)。这种风格比f(g(x))这样的嵌套函数调用更捐业。
去了解一些应用程序如何工作,并尝试适应无“.”风格。
逐步开始写代码,用交互窗口来测试代码段。如果你盲目的搞一大堆代码,然后想一次编过,你可能终将得到一堆恶心难调的编译错误。

以上是关于F#之旅2 - 我有特别的学F#技巧的主要内容,如果未能解决你的问题,请参考以下文章

JSF f:event preRenderView 是由 f:ajax 调用和部分渲染触发的,还有别的吗?

F盘提示此卷不包含可识别的文件系统要怎么办啊

tail:执行tail -f时无法识别的文件系统类型错误

放松 Segue 还是别的啥?

Swift:由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:无法识别的选择器发送到实例 0x7fb179f12260'

F#之旅0 - 开端