2012年3月30日星期五

How to learn Haskell


I’m going to order this guide by the level of skill you have in haskell, going from an absolute beginner right up to an expert. Note that this process will take many months (years?), so it is rather long.我将根据你的haskell水平写这个指导,从初级菜鸟到专家级别。注意这个修炼过程很长,需要很多个月(年?)来达成。
Absolute Beginner
完全新手
Firstly, haskell is capable of anything, with enough skill. It is very fast (behind only c and c++ in my experience), and can be used from anything from simulations, servers, guis and web applications.
首先,只要水平到家,haskell适用于任何领域。它非常快(据我的经验,只比C和C++慢点),而且可以用在任何领域,从模拟计算,服务器,界面直到web应用。
However there are some problems that are easier to write for a beginner in haskell than others. Mathematical problems and list process programs are good candidates for this, as they only require the most basic of haskell knowledge to be able to write.
但是对于初学者来说,有些问题用haskell更容易些。数学问题和列表处理程序就是代表,它们只需要最基本的haskell知识。
Firstly, a good guide to learning the very basics of haskell is the first 6 chapters of learn you a haskell. While reading this, it is a very good idea to also be solving simple problems with what you know.
首先,关于haskell基础知识有个非常好的教程,就是的前六章。在阅读它的同时,最好也用你学到的知识来解决些简单的问题。
A good list of problems to try is the haskell 99 problems page. These start off very basic, and get more difficult as you go on. It is very good practice doing a lot of those, as they let you practice your skills in recursion and higher order functions. I would recommend skipping any problems that require randomness as that is a bit more difficult in haskell.
有一个很好的问题集,是haskell 99 problems page。它从最基本的开始,一点一点增加难度。多做些上面的题目是很好的实践,因为你可以练习递归和高阶函数的技巧。我推荐如果遇到需要随机数的题目,就先跳过它,因为这个在haskell里有点搞。
Once you have done a few of those, you could move on to doing a few of the Project Euler problems. These are sorted by how many people have completed them, which is a fairly good indication of difficulty. These test your logic and haskell more than the previous problems, but you should still be able to do the first few. A big advantage haskell has with these problems is Integers aren’t limited in size. To complete some of these problems, it will be useful to have read chapters 7 and 8 of learn you a haskell as well.
当你做好了一些题,也可以考虑转战 Project Euler. 这里的题目是按照完成人数来排序的,也显示它们的难度。它们要比前面的题目要更考验你的逻辑和haskell技术,但是你也应该可以完成比较靠前的题目。用haskell做这些题目有个优势,就是Integers没有size限制。你可能需要读读的第七和第八章。
Beginner
初学者
After that you should have a fairly good handle on recursion and higher order functions, so it would be a good time to start doing some more real world problems. A very good place to start is Real World Haskell (online book, you can also purchase a hard copy). I found the first few chapters introduced too much too quickly for someone who has never done functional programming/used recursion before. However with the practice you would have had from doing the previous problems you should find it perfectly understandable.
当你比较了解递归和高阶函数之后,差不多是时候来解决点真正的问题了。(有在线的免费版本,也可以上书店买印刷版)是一个很好的开始。如果你以前没有接触过函数式编程,不了解递归的概念,前几章会很吃力,但是如果你已经有了前面的练习,你就会发现它很好理解。
Working through the problems in the book is a great way of learning how to manage abstractions and building reusable components in haskell. This is vital for people used to object-orientated (oo) programming, as the normal oo abstraction methods (oo classes) don’t appear in haskell (haskell has type classes, but they are very different to oo classes, more like oo interfaces). I don’t think it is a good idea to skip chapters, as each introduces a lot new ideas that are used in later chapters.
理解这本书上的问题是学习如何在haskell中管理抽象和构建可复用组件的好方法。对于那些习惯于面向对象编程的人尤为重要,因为haskell并不包含通常的面向对象抽象方法(haskell中有type类,但是它和class完全不同,更像是interface)。我觉得最好不要跳过章节,因为每一章都介绍了很多新内容,会在后面的章节用到。
After a while you will get to chapter 14, the dreaded monads chapter (dum dum dummmm). Almost everyone who learns haskell has trouble understanding monads, due to how abstract the concept is. I can’t think of any concept in another language that is as abstract as monads are in functional programming. Monads allows many ideas (such as IO operations, computations that might fail, parsing,…) to be unified under one idea. So don’t feel discouraged if after reading the monads chapter you don’t really understand them. I found it useful to read many different explanations of monads; each one gives a new perspective on the problem. Here is a very good list of monad tutorials. I highly recommend the All About Monads, but the others are also good.
不一会你就到了第14章,传说中令人畏惧的monads。基本上每一个haskell学习者在曾在理解monads上有过困难,因为这个概念太抽象了。我没见过其它什么语言里有比这还抽象的概念。Monads允许很多不同的概念(比如IO操作,可能失败的计算,解析等)都被统一到一个大的概念下。所以当你读完这一章觉得没有弄懂时,不要灰心。读读其它的对monads的解说会有些帮助,通常都会展示一个新的视角。这里有一个monad教程的列表list of monad tutorials。我很推崇这篇All About Monads,不过其它的也不错。
Also, it takes a while for the concepts to truly sink in. This comes through use, but also through time. I find that sometimes sleeping on a problem helps more than anything else! Eventually, the idea will click, and you will wonder why you struggled to understand a concept that in reality is incredibly simple. It is awesome when this happens, and when it does, you might find haskell to be your favorite imperative programming language :)
当然,真正完全理解还需要一段时间。理解通常需要练习,这也需要时间。我发现有时候带着问题睡觉非常有用。最终,当灵感来了,你会奇怪为什么你会在这么简单的概念上挣扎这么久。这种感觉很带劲,当你有这种感觉时,你大概觉得haskell是你的最爱了。
To make sure that you are understanding Haskell type system perfectly, you should try to solve 20 intermediate haskell exercises. Those exercises using fun names of functions like “furry” and “banana” and helps you to have a good understanding of some basic functional programming concepts if you don’t have them already. Nice way to spend your evening with list of paper covered with arrows, unicorns, sausages and furry bananas.
如果想要完全理解haskell的类型系统,你应该去试试 20 intermediate haskell exercises. 在这些练习里,函数名都很有趣,比如”furry”还有”banana”,帮助你理解基本的函数式编程概念。晚上花些时间在这些箭头,独角兽,香肠和香蕉皮(应该都是函数名)上是个不错的选择。
Intermediate
中级
Once you understand Monads, I think you have made the transition from a beginner haskell programmer to an intermediate haskeller. So where to go from here? The first thing I would recommend (if you haven’t already learnt them from learning monads) is the various types of monads, such as Reader, Writer and State. Again, Real world haskell and All about monads gives great coverage of this. To complete your monad training learning about monad transformers is a must. These let you combine different types of Monads (such as a Reader and State monad) into one. This may seem useless to begin with, but after using them for a while you will wonder how you lived without them.
一旦你理解了monads,我认为你就从haskell初学者转变为中级水平了。现在应该怎么走?首先我推荐的是不同类型的monads(如果你在学习时还没学到的话),比如Reader,Writer和State。覆盖全部这些。nonad变换也是monad学习中的必须一部分。它们让你把不同类型的monads合并到一起(比如Reader和State monads)。开始可能觉得没有什么用,但是用了一阵后就觉得离不开它们了。
Now you can finish the real world haskell book if you want. Skipping chapters now though doesn’t really matter, as long as you have monads down pat. Just choose what you are interested in.
如果你想,现在你可以把看完了。只要你弄明白了monads,跳跳章节没问题,选择自己感兴趣的看看。
With the knowledge you would have now, you should be able to use most of the packages on cabal (well the documented ones at least…), as well as most of the libraries that come with haskell. A list of interesting libraries to try would be:
以你现在的知识,可以去玩玩大多数的cabal里的package了,包括大多数的haskell库。下面是一些有意思的库:
  • Parsec: for parsing programs and text. Much better than using regexps. Excellent documentation, also has a real world haskell chapter.
  • Quickcheck: A very cool testing program. What you do is write a predicate that should always be true (eg length (reverse lst) == length lst). You then pass the predicate the quickCheck, and it will generate a lot of random values (in this case lists) and test that the predicate is true for all results. See also the online manual.
  • HUnit: Unit testing in haskell.
  • gtk2hs: The most popular gui framework for haskell, lets you write gtk applications in haskell.
  • happstack: A web development framework for haskell. Doesn’t use databases, instead a data type store. Pretty good docs (another framework would be Turbinado, haven’t tried it yet though).
  • Parsec: Parser库,比正则表达式强多了,文档很棒,而且在real world haskell中有一章介绍。
  • Quickcheck:一个很酷的测试程序。只需要指定真断言(比如length (reverse lst) == length lst), 然后把这个断言传给quickCheck,然后它会产生随机数据(这个例子里是list)来测试这个断言是否为真,可以看在线文档 online manual.
  • HUnit:haskell单元测试。
  • gtk2hs:最流行的gui框架,可以用haskell写gtk程序。
  • happstack: 一个haskell web开发框架,没有使用数据库,而是使用data type store。文档很棒。(另一个是Turbinado, 不过没有试过)
Also, there are many concepts (like the Monad concept) that you should eventually learn. This will be easier than learning Monads the first time, as your brain will be used to dealing with the level of abstraction involved. A very good overview for learning about these high level concepts and how they fit together is the typeclassopedia article (about half way through, pdf)
而且你最终还会学到很多概念(就像monad)。因为你头脑已经适应这种程度的抽象了,所以不会像当初学习monads时那么难。一个很好的关于这些高阶概念的总结和它们怎么结合在一起的文档是typeclassopedia article
  • Applicative: An interface like Monads, but less powerful. Every Monad is Applicative, but not vice versa. This is useful as there are some types that are Applicative but are not Monads. Also, code written using the Applicative functions is often more composable than writing the equivalent code using the Monad functions. SeeFunctors, Applicative Functors and Monoids from the learn you a haskell guide.
  • Foldable,Traversable: Typeclasses that abstract many of the operations of lists, so that the same functions can be applied to other container types. See also the haskell wiki explaination.
  • Monoid: A Monoid is a type that has a zero (or mempty) value, and an operation that joins two Monoids together, such that operation x mempty = x. Many types are Monoids, such as numbers, with mempty = 0 and operation = plus. This is useful in many situations.
  • Arrows: Arrows are a way of representing computations that take an input and return an output. A function is the most basic type of arrow, but there are many other types. The library also has many very useful functions for manipulating arrows – they are very useful even if only used with plain old haskell functions.
  • Arrays: the various mutable/immutable arrays in haskell.
  • ST Monad: lets you write code with a mutable state that runs very quickly, while still remaining pure outside the monad. See the link for more details.
  • FRP: Functional Reactive Programming, a new, experimental way of writing code that handles events, triggers, inputs and outputs (such as a gui). I don’t know much about this though.
  • Applicative:一个类似的monads的接口,没有那么强大。每个monad都是Applicative,但是反过来不是。当某些类型是Applicative但是不是monads时,这个概念就很有用。而且,利用applicative写程序要比相同的功能用monads来实现要容易理解,比如haskell趣学指南中的Functors, Applicative Functors and Monoids
  • Foldable,Traversable: 抽象了很多list操作的Typeclasses,这样相同的函数可以作用在很多不同的容器类型上。可见到 haskell wiki explaination.
  • Monoid:只包含0(或者mempty)的monads和一个操作把两个Monoids合并,比如operation x mempty = x.很多类型都是Monoids,比如Number加上mempty = 0和operation=plus。这些在很多情况上都有用。
  • Arrows:一种表示拿一个输入在return一个输出的计算。函数是最为基本的arrow,当然也有其它的类型。库里也有很多操作arrows的函数,这些函数对于操作普通haskell函数也很有用。
  • Arrays:haskell中可变和不可变的队列。
  • ST Monad:可以在一个快速的可变状态中编程,而对于外部还是纯函数的。
  • FRP:函数式反应编程,一种新的,实验性的编程方法。可以处理事件,触发器,输入和输出(比如gui)
There are a lot of new language features you should have a look at. I’ll just list them, you can find lots of info about them from google, the haskell wikibook, the haskellwiki.org site and ghc documentation.
有很多语言特性,你可以去研究。我列出了一些,你可以自行google之,或者查haskell wikibook, the haskellwiki.org site 和 ghc documentation.
  • Multiparameter type classes/functional dependencies
  • Type families
  • Existentially quantified types
  • Phantom types
  • GADTS
  • others…
  • 多参数type classed/函数依赖
  • 类型族
  • 存在限定类型
  • 影子类型
  • GADTS
  • 其它….
A lot of haskell is based around category theory, so you may want to look into that. Unfortunately I don’t know any good links for learning category theory for beginners.
haskell基本都是建立在范畴论上的,所以你也可能需要看看。可惜我不知道有什么资料推荐给初学者。
Finally you will want to learn more about the various haskell tools. These include:
最后你也要学点haskell的工具,包括:
  • ghc (and all its features)
  • cabal: the haskell package system
  • darcs: a distributed version control system written in haskell, very popular for haskell programs.
  • haddock: a haskell automatic documentation generator
  • ghc 和它的特性
  • cabal haskell包系统
  • darcs:haskell写的分布式版本管理系统,haskell界很流行
  • haddock:haskell的自动文档生成
While learning all these new libraries and concepts, it is very useful to be writing a moderate-sized project in haskell. It can be anything (eg a small game, data analyser, website, compiler). Working on this will allow you to apply many of the things you are now learning. You stay at this level for ages (this is where I’m at).
当学习这些库和概念时,写个中型项目会比较好。随便什么都好(比如小游戏,数据分析,网站,编译器)。做这些可以把你所学的都用上。你可能会在这个阶段停留很久(我就是这样)
Expert
专家
It will take you years to get to this stage (hello from 2009!), but from here I’m guessing you start writing phd papers, new ghc extensions, and coming up with new abstractions.
这个可要好多年才能到这个阶段,到了这个阶段,你大概在写博士论文,新的ghc扩展,和新的抽象结构。
Getting Help
寻求帮助
Finally, while at any stage of learning, there are multiple places for getting information. These are:
最后,在学习过程中,很多地方可以获得帮助,包括:
  • the #haskell irc channel
  • the mailing lists. These are worth signing up for just to read the discussions that take place – some are very interesting.
  • other places listed on the haskell.org home page
  • #haskell irc频道
  • 邮件组,很值得去注册,很多讨论很有趣,值得一读。
  • haskell.org上列出来一些地方
Conclusion
结论
Well this turned out longer than I expected… Anyway, I think it is a very good idea to become proficient in haskell. It takes a long time, but that is mainly because you are learning a completely new way of thinking by doing so. It is not like learning ruby after learning java, but like learning java after learning c. Also, I am finding that my object-orientated programming skills have improved as a result of learning haskell, as I am seeing many new ways of abstracting ideas.
我写得比我打算的要长点…不管怎样,我觉得熟练掌握haskell是个很棒的主意。需要很长的时间,但是这是因为你在学习一种全新的思考方式,和学完java之后学习ruby不一样,比较像学完C后学习java。而且,学了haskell后,我觉得我的面向对象功力也增长了,因为我有了很多新的抽象概念。

没有评论: