原文地址: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#技巧的更多相关文章

  1. F#之旅4 - 小实践之快排

    参考文章:https://swlaschin.gitbooks.io/fsharpforfunandprofit/content/posts/fvsc-quicksort.html F#之旅4 - 小 ...

  2. F#之旅0 - 开端

    F#之旅0 - 开端 UWP的学习告一段落,CozyRSS的UWP版本并没有做.UWP跟wpf开发几乎一模一样,然后又引入了很多针对移动设备的东西,这部分有点像android.没啥太大的意思,不难,估 ...

  3. F# 之旅(上)

    写在前面的话 解答一下在上一篇文章<在Visual Studio中入门F#>中有人的提问, 1. 问:是准备写 F# 系列吗?    答:当然不是,本人也是刚刚学习 F#,只是翻译微软官方 ...

  4. F# 之旅(下)

    写在前面的话 学习 F# 一定要去体会函数式编程的特点,推荐一下阮一峰的日志<函数式编程入门教程>. 在这篇文章中 递归函数 记录和可区分联合类型 模式匹配 可选类型 度量单位 类和接口 ...

  5. F#之旅9 - 正则表达式

    今天,cozy群有个群友发了条正则,问正则匹配相关的问题.虽然他的问题用html selector去处理可能更好,但是我也再一次发现:我忘了正则怎么写的了! 忘掉正则是有原因的,这篇文章会简单记录下F ...

  6. F#之旅8 - 图片处理应用之动画二维码

    首先,先介绍下什么是动画二维码.前些天在网上闲逛,突然看到一个开源项目,发现一种二维码的新玩法.https://github.com/sylnsfar/qrcode/blob/master/READM ...

  7. F#之旅6 - 简单AV推荐系统

    上回说到用F#来写爬虫,这只是F#学习第一阶段的第一步.最开始,就对第一阶段做了这样的安排: 1.爬虫爬取AV数据 2.数据处理和挖掘 3.数据可视化(使用ECharts) 4.推荐系统 第一步很快就 ...

  8. F#之旅5 - 小实践之下载网页(爬虫基础库)

    参考文章:https://swlaschin.gitbooks.io/fsharpforfunandprofit/content/posts/fvsc-download.html 参考的文章教了我们如 ...

  9. F#之旅3 - F# PK C#:简单的求和

    原文链接:https://swlaschin.gitbooks.io/fsharpforfunandprofit/content/posts/fvsc-sum-of-squares.html Comp ...

随机推荐

  1. api接口类型

    类型一:js+xml 类型二:纯php模式 参考: <?php $ip = '117.25.13.123'; $datatype = 'text'; $url = 'http://api.ip1 ...

  2. redis 常用命令

    临时启动:redis-server.exe redis.conf/redis-server redis.windows.conf安装Windows服务:redis-server.exe --servi ...

  3. jQuery $(document).ready() 与window.onload的区别

    ps:jQuery中$(document).ready()的作用类似于传统JavaScript中的window.onload方法,虽然具有类似的效果,但是它们在触发操作的时间上存在着微妙的差异. 在j ...

  4. Android之ListView性能优化——使用ConvertView和ViewHolder

    使用ConvertView和ViewHolder的优化是针对ListView的Adapter(BaseAdapter)的.这种优化的优点如下: 1)重用了ConveertView,在很大程度上减少了内 ...

  5. SQL Server数据库定时自动备份

    SQL Server 数据库定时自动备份[转]   在SQL Server中出于数据安全的考虑,所以需要定期的备份数据库.而备份数据库一般又是在凌晨时间基本没有数据库操作的时候进行,所以我们不可能要求 ...

  6. TinkPad E40 CentOS 6.5 无线网卡驱动 RTL8191SEvB 安装

    最近把一台老本TinkPad E40 安装了CentOS 6.5 其他都没什么问题,唯独没有无线网卡驱动. 通过命令: lspci | grep Network 查看无线网卡型号: 然后去瑞昱官网找驱 ...

  7. Ubuntu 手动更新firefox的flash插件

    Ubuntu下 Firefox更新flash插件老是提示失败,自己动手丰衣足食啊. 1.下载tar文件,地址:http://get.adobe.com/cn/flashplayer/?no_redir ...

  8. Javascript设计模式学习三(策略模式)

    定义:定义一系列的算法,把它们一个个封装起来,并且使它们可以互相替换.目的:将算法的使用和算法的实现分离开来.比如: if(input == 'A'){ return 1; } if(input == ...

  9. linux centos 6.5下安装nodejs

    1.将文件下载或拷贝至/usr/local/src目录下,可使用xshell工具上传文件 2.解压缩文件: tar xvf /usr/local/src/node-v6.9.2-linux-x64 3 ...

  10. Redis常用操作及客户端工具

    修改redis密码 打开redis.windows.conf,找到requirepass  设置密码重启服务即可 将redis安装为windows服务,批处理如下: redis-server.exe ...