Haskell入门

and*_*vig 755 haskell functional-programming

几天后,我试图围绕Haskell中的函数式编程范例.我通过阅读教程和观看截屏视频来完成这项工作,但似乎没有什么能够坚持下去.现在,在学习各种命令式/ OO语言(如C,Java,PHP)时,练习对我来说是个好方法.但由于我不知道Haskell能够做什么,并且因为有许多新概念可供使用,我还不知道从哪里开始.

那么,你是如何学习Haskell的?是什么让你真正"打破僵局"?还有开始练习的好主意吗?

Dav*_*ani 2447

我将按照你在haskell中的技能水平订购本指南,从绝对的初学者到专家.请注意,此过程需要几个月(几年?),所以它相当长.

绝对的菜鸟

首先,haskell能够胜任任何事情,具备足够的技能.它非常快(在我的经验中只有c和c ++之后),并且可以用于从模拟到服务器,guis和web应用程序的任何事情.

但是,有些问题比haskell更容易为haskell的初学者编写.数学问题和列表处理程序是很好的选择,因为它们只需要最基本的haskell知识才能编写.

首先,学习haskell基础知识的一些很好的指南是快乐学习haskell教程和前6章学习你的haskell.在阅读这些内容时,同样用您所知道的解决简单问题也是一个非常好的主意.

另外两个好的资源是来自第一原理的Haskell编程Haskell中的编程.他们都为每一章都附带练习,所以你有一些小问题与你在最后几页学到的东西相匹配.

要尝试的一个很好的问题列表是haskell 99问题页面.这些开始非常基础,并且随着你的继续变得更加困难.这很好的做法很多,因为它们让你练习递归和高阶函数的技能.我建议跳过任何需要随机性的问题,因为在haskell中这有点困难.如果您想使用QuickCheck测试解决方案,请查看此问题(请参阅下面的中间版).

一旦你完成了其中的一些,你就可以继续做一些Project Euler问题.这些是根据完成它们的人数排序的,这是一个相当好的困难迹象.这些测试你的逻辑和haskell比以前的问题更多,但你仍然应该能够做到前几个.haskell具有这些问题的一大优势是整数不受大小限制.要完成其中的一些问题,阅读第7章和第8章,了解一下你也是有用的.

初学者

在那之后你应该对递归和更高阶函数有一个相当好的处理,所以这是开始做一些更真实的世界问题的好时机.一个非常好的起点是Real World Haskell(在线书籍,你也可以购买一份硬拷贝).我发现前几章对于从未完成函数式编程/使用递归的人来说太快了.然而,通过练习以前遇到的问题,您应该会发现它完全可以理解.

解决本书中的问题是学习如何在haskell中管理抽象和构建可重用组件的好方法.这对于习惯于面向对象(oo)编程的人来说至关重要,因为正常的oo抽象方法(oo类)没有出现在haskell中(haskell有类型类,但它们与oo类非常不同,更像是oo接口).我不认为跳过章节是个好主意,因为每个章节都会引入很多新的想法,这些想法将在后面的章节中使用.

过了一会儿,你将进入第14章,可怕的monads章节(dum dum dummmm).由于概念的抽象程度,几乎所有学习haskell的人都难以理解monad.我想不出另一种语言中的任何概念,就像monad在函数式编程中一样抽象.Monads允许在一个想法下统一许多想法(例如IO操作,可能失败的计算,解析......).因此,如果在阅读了monad章节后你并不真正理解它们,请不要气馁.我发现阅读monad的许多不同解释很有用; 每个人都对这个问题提出了新的看法.这是一个非常好的monad教程列表.我强烈推荐All About Monads,但其他人也很好.

此外,概念需要一段时间才能真正沉入其中.这可以通过使用,也可以通过时间来实现.我发现有时睡在一个问题上比其他任何事情更有帮助!最终,这个想法会点击,你会想知道为什么你很难理解一个实际上非常简单的概念.当这种情况发生时很棒,当它发生时,你可能会发现haskell是你最喜欢的命令式编程语言:)

为了确保您完全理解Haskell类型系统,您应该尝试解决20个中级haskell练习.这些练习使用有趣的名称,如"毛茸茸"和"香蕉",并帮助您很好地理解一些基本的函数式编程概念,如果你还没有它们.晚上用箭头,独角兽,香肠和毛茸茸的香蕉覆盖的纸张列表的好方法.

中间

一旦你理解了Monads,我认为你已经从初学者haskell程序员转变为中级haskeller.那么从哪里开始呢?我建议的第一件事(如果你还没有从学习monad中学到它们)是各种类型的monad,例如Reader,Writer和State.再一次,真实的世界haskell和所有关于monads给予了很好的报道.要完成你的monad训练,学习monad变形金刚是必须的.这些允许您将不同类型的Monad(例如Reader和State monad)组合成一个.这可能看起来没用,但是在使用它们一段时间之后你会想知道没有它们你是如何生活的.

现在你可以根据需要完成现实世界的哈斯克书.现在跳过章节并不重要,只要你有monads拍下来.只需选择您感兴趣的内容即可.

凭借您现在拥有的知识,您应该能够使用cabal上的大多数软件包(至少是文档中的软件包),以及haskell附带的大多数库.要尝试的有趣库列表如下:

  • Parsec:用于解析程序和文本.比使用正则表达式好多了.优秀的文档,还有一个现实世界的haskell章节.

  • 快速检查:一个非常酷的测试程序.你所做的是写一个应该永远为真的谓词(例如length (reverse lst) == length lst).然后,您将谓词传递给quickCheck,它将生成大量随机值(在本例中为列表),并测试谓词对于所有结果都为真.另请参阅在线手册.

  • HUnit:haskell的单元测试.

  • gtk2hs:haskell最流行的gui框架,让你在haskell中编写gtk应用程序.

  • happstack:haskell的web开发框架.不使用数据库,而是使用数据类型存储.非常好的文档(其他流行的框架将是快照yesod).

此外,您应该最终学习许多概念(如Monad概念).这将比第一次学习Monads更容易,因为你的大脑将用于处理所涉及的抽象级别.关于这些高级概念以及它们如何组合在一起的非常好的概述是Typeclassopedia.

  • 适用:像Monads这样的界面,但功能较弱.每个Monad都是适用的,但反之亦然.这很有用,因为有些类型是Applicative但不是Monads.此外,使用Applicative函数编写的代码通常比使用Monad函数编写等效代码更具组合性.请参阅学习哈克尔指南中的Functors,Applicative Functors和Monoids.

  • 可折叠,可遍历:抽象列表的许多操作的类型类,以便相同的函数可以应用于其他容器类型.另见haskell wiki解释.

  • Monoid:Monoid是一种具有零(或mempty)值的类型,以及一个<>将两个Monoid 连接在一起的操作,例如x <> mempty = mempty <> x = xx <> (y <> z) = (x <> y) <> z.这些被称为身份和相关性法律.许多类型都是Monoids,例如数字,mempty = 0<> = +.这在许多情况下都很有用.

  • 箭头:箭头是表示采用输入并返回输出的计算的一种方式.函数是最基本的箭头类型,但还有许多其他类型.该库还具有许多非常有用的操作箭头的功能 - 即使仅用于普通的旧的haskell功能,它们也非常有用.

  • 数组:haskell中的各种可变/不可变数组.

  • ST Monad:允许你编写一个运行速度非常快的可变状态的代码,同时在monad之外仍保持纯粹.请参阅链接查看更多细节.

  • FRP:功能反应编程,一种编写处理事件,触发器,输入和输出(例如gui)的代码的新的实验方法.我对此并不了解.Paul Hudak关于yampa的谈话是一个好的开始.

您应该查看许多新的语言功能.我只是列出它们,你可以从google,haskell wikibook,haskellwiki.org网站和ghc文档中找到很多关于它们的信息.

  • 多参数类型类/函数依赖项
  • 输入家庭
  • 存在量化的类型
  • 幻影类型
  • GADTS
  • 其他...

很多haskell基于类别理论,所以你可能想要研究它.一个很好的起点是计算机科学家的类别理论.如果你不想买这本书,作者的相关文章也很棒.

最后,您需要了解有关各种haskell工具的更多信息.这些包括:

  • ghc(及其所有功能)
  • cabal:haskell包装系统
  • darcs:用haskell编写的分布式版本控制系统,非常受haskell程序的欢迎.
  • haddock:一个haskell自动文档生成器

在学习所有这些新的库和概念时,在haskell中编写一个中等大小的项目非常有用.它可以是任何东西(例如小游戏,数据分析器,网站,编译器).通过这项工作,您可以应用许多您正在学习的内容.你可以长时间呆在这个级别(这就是我所处的位置).

专家

你需要几年的时间才能进入这个阶段(你好,从2009年开始!),但是从这里我猜你开始写博士论文,新的ghc扩展,以及提出新的抽象.

获得帮助

最后,在学习的任何阶段,获取信息的地方有很多.这些是:

  • #haskell irc频道
  • 邮件列表.这些值得注册只是为了阅读发生的讨论 - 有些非常有趣.
  • haskell.org主页上列出的其他地方

结论

好吧,这比我预期的要长......无论如何,我认为精通haskell是一个非常好的主意.这需要很长时间,但这主要是因为你正在学习一种全新的思维方式.它不像学习java之后学习ruby,而是像学习c之后学习java一样.此外,我发现由于学习haskell,我的面向对象编程技能得到了提高,因为我看到了很多抽象思路的新方法.

  • 耶箭!首先你让monad塑造你的大脑,然后你站在你的头上思考comonads,然后你同时做两个箭头:)在Haskell中有很多表达力量可以打开类型级别编程也是. (34认同)
  • @nanothief`Monad`更强大,但也更少成分...很多人使用monad,他们可以用更清洁的`Applicative`代码.大多数的东西都是`Functor`s'也是`Monad',但是当`fmap`就足够了,你不会使用`>> =`和`return`,因为后者会导致更简单的代码,如果可以的话用它. (13认同)
  • @pelotom,我添加了typeclassopedia链接以及使用Applicative到该部分的更好理由,并删除了Functor部分.由于在大多数教材(包括RWH)中强调Monads,因此很难使Monad和Applicative概念得到正确的顺序.另一方面,教我一个haskell教程已经走了很长的路,因为我最初写的答案(近2年:O),并在Monad之前教授Applicative,也许现在应该是学习haskell的推荐方式. (8认同)
  • @tomf:谢谢!我一直对这个答案的表现感到惊讶 - 自从我写这篇文章以来已经差不多五年了,但它仍然很强大.我很快就需要对它进行更新,因为它有点过时了.它没有提到镜头,管道,约束种类,haskell平台,类型级别数字,并且它们是自写这篇文章以来非常重要的新主题.你是对的,RWH不再那么好了,它在很长一段时间内没有更新,很多例子都没有编译.无论如何,我很高兴它对你仍然有帮助. (5认同)
  • 很棒的建议.我是在一年多前开始的,而且大部分时间都在中级阶段.反馈:RWH的monad章节(第14章)解释不清楚.阅读RWH的在线版本是有益的,因为它包含有助于本章的众包评论.FWIW,[你可能已经发明了Monads]​​(http://blog.sigfpe.com/2006/08/you-could-have-invented-monads-and.html),是最适合我的monad教程. (2认同)
  • 嘿,我认为我们也应该添加 Chris Allen [来自第一原则的 Haskell 编程](http://haskellbook.com/) 的这本书。这也是一本好书。 (2认同)
  • @hasufell:是的,这个问题已经过时了(它是在2009年写的,自那以后就没多少了).RWH非常过时,因为它是在管道/镜头/堆叠之前编写的.LYAH确实有它的缺点,但当时我觉得这是最好的简单介绍haskell免费提供.不幸的是,自2009年以来,似乎haskell的学习资源已经恶化,因为现在没有像RHW那样免费提供.在learnhaskell github链接中推荐的课程是可以的,但在整个课程中你似乎没有做任何实际的(除了解析). (2认同)

jit*_*ter 176

我的一些同事在学习你是一个很好的Haskell时有很好的经验!.

该教程针对的是那些具有命令式编程语言经验但之前没有使用函数式语言编程的人.

并核对答案在这里

  • 我是第二个.此外,由于它不是很明显,这里有一个可下载的pdf版本教程的链接:http://learnyouahaskell.com/learnyouahaskell.pdf网页设计很棒,但我也喜欢有地铁副本. (27认同)
  • 我从这开始,但我的意见是你应该直接去真实世界Haskell.不同之处就像从K&R学习C或"C for dummies"试图变得简单,但是用它的方法错过了重要的东西.我认为最好直接了解事实,而不是试图学习Haskell"必要的方式". (8认同)
  • 我非常喜欢这个,我在这个和真实世界的Haskell上花了很多时间.IMO,"了解你一个Haskell"提供了比真实世界Haskell更深刻的洞察力,尽管它们都是很好的资源. (7认同)
  • @ abababa22我认为首先阅读LYAH然后去RWH是最好的主意.LYAH不会教你Haskell; 它教你功能编程.当你解决问题时,你开始以功能的方式思考.很明显,只有LYAH不足以编写一个大型应用程序,但它会以正确的方式使你的思想弯曲.如果你来自势在必行,这是最好的方式,IMO (7认同)
  • @Telemachus请注意:PDF不是最终版本,至少它缺少最后一章. (3认同)

Dav*_*one 102

这是一本很好的书,你可以在网上阅读:真实世界Haskell

我所做的大多数Haskell程序都是为了解决Project Euler问题.

我不久前读到的一条建议就是你应该有一套标准的简单问题,你知道如何解决(理论上),然后每当你尝试学习一门新语言时,你就会用那种语言来实现这些问题.

  • +1好建议 - 其他来源:Wikibooks (4认同)
  • 根据我的经验,Real World Haskell 很棒,直到你到达第 5 章。从那时起我不会推荐它。 (3认同)

eev*_*var 73

我很高兴看到使用Haskell的13集关于功能编程的系列剧.

C9讲座:Erik Meijer博士 - 功能编程基础知识:http: //channel9.msdn.com/shows/Going+Deep/Lecture-Series-Erik-Meijer-Functional-Programming-Fundamentals-Chapter-1/


yai*_*chu 69

要添加其他人的答案 - 有一个有用的,可以帮助您编码时(例如解决项目欧拉问题时): Hoogle.您可以使用命令行界面或Web界面.

命令行

安装Haskell平台后一定要确保 cabal install hoogle

Hoogle用法示例:

你有一个函数f x = 3 * x + 1,你想要应用它(5 :: Int),然后将它应用于结果和结果,依此类推,并获得这些值的无限列表.您怀疑可能已经存在帮助您的功能(不是专门针对您的f).

该函数将类型的(a -> a) -> a -> [a],如果它需要f 5或者a -> (a -> a) -> [a]如果它需要5 f(我们假设该功能对于一般类型,而不仅仅是Int为s)

$ hoogle "a -> (a -> a) -> [a]"
Prelude iterate :: (a -> a) -> a -> [a]
Run Code Online (Sandbox Code Playgroud)

是的,你需要的功能已经存在并被调用iterate.你用它iterate func 5!

Web界面

可以在此处找到相同示例的结果.


Cur*_*son 57

Graham Hutton 在Haskell编程简洁,相当彻底,他多年的Haskell教学真正展现出来.这几乎总是我建议人们开始的,无论你从哪里开始.

特别是,第8章("功能解析器")提供了开始处理monad所需的真正基础,我认为这是迄今为止最好的起点,其次是All About Monads.(关于那一章,请注意网站上的勘误表:但是如果do没有一些特殊的帮助,你就无法使用该表格.你可能想先了解类型类并自己解决这个问题.)

Haskell的初学者很少强调这一点,但是不仅要及早学习使用monad,而且要构建自己的monad.这并不难,定制的任务可以使许多任务变得更加简单.

  • 这是一本完全不被重视的书(和答案).关于功能解析器的章节,接下来是关于IO的章节,它们都没有提到monad,它真的是一种优雅的教学方法. (4认同)

Joh*_*ith 51

不要尝试用有趣的比喻阅读所有monad教程.它们会让你更加混乱.

  • 同意!请参阅'抽象,直觉和"monad教程谬误":http://byorgey.wordpress.com/2009/01/12/abstraction-intuition-and-the-monad-tutorial-fallacy/ (5认同)

sha*_*apr 31

我建议加入#haskell irc频道并在那里提问.这就是我学习Haskell的方式.如果您按照上面的建议浏览Real World Haskell,那么实时回答您的问题将会有很大帮助.#haskell上的很多聪明人写Haskell是为了娱乐和赚钱,所以你会得到很多好的输入.试试吧!

  • +1 - 要清楚:使用irc通道_not_了解它_just_.如同,请不要进去询问"如何编写haskell程序?如何添加数字?" (5认同)
  • 并阅读你加入的任何频道的/主题:) (2认同)

Son*_*nül 24

这些是我的最爱

Haskell:带类型的函数式编程

Joeri van Eekelen, et al. | Wikibooks
       Published in 2012, 597 pages
Run Code Online (Sandbox Code Playgroud)

真实世界哈斯克尔

   B. O'Sullivan, J. Goerzen, D. Stewart | OReilly Media, Inc.
   Published in 2008, 710 pages
Run Code Online (Sandbox Code Playgroud)


Gre*_*g S 19

我还可以推荐Yet Another Haskell Tutorial作为介绍.

另一个很好的学习资源(可能在中级水平),这对我帮助很大,而且在我看到的其他答案中没有被提及,是Brent Yorgey的Typeclassopedia,可以在The Monad Reader中找到(问题13)

它以非常易于访问的方式编写,并包含(以及许多其他内容),以下介绍性建议:

专家Haskell黑客的智慧有两个关键:

  1. 了解类型.

  2. 通过熟悉许多示例,可以为每个类型及其与其他类型类的关系获得深刻的直觉.

Monad Reader本身是功能程序员(不仅仅是Haskell程序员)的绝对宝库.


ala*_*mar 14

尝试在其中编写简单的程序.

您可以在各种教科书中找到示例任务.

我不建议坚持使用Haskell/FP教科书,只是尝试用它做简单的事情:计算,字符串操作,文件访问.

在我解决了十几个之后,我打破了冰:)

之后,阅读很多高级概念(Monads,Arrows,IO,递归数据结构),因为haskell是无限的,并且有很多.


sno*_*now 14

我认为通过示例实现Haskell的功能是最重要的开始.

http://en.wikipedia.org/wiki/Haskell_98_features

这是棘手的类型,包括monad和箭头

http://www.haskell.org/haskellwiki/Typeclassopedia

对于现实问题和更大的项目,请记住这些标签:GHC(最常用的编译器),Hackage(libraryDB),Cabal(建筑系统),darcs(另一种建筑系统).

集成系统可以节省您的时间:http://hackage.haskell.org/platform/

该系统的包数据库:http://hackage.haskell.org/

GHC编译器的wiki:http://www.haskell.org/haskellwiki/GHC

在Haskell_98_features和Typeclassopedia之后,我想您已经可以自己找到并阅读有关它们的文档

顺便说一句,你可能想测试一些GHC的语言扩展,这可能是将来haskell标准的一部分.

这是我学习haskell的最佳方式.我希望它可以帮助你.


Ray*_*yne 13

我建议你首先阅读BONUS的教程,然后阅读Real World Haskell(免费在线).加入irc.freenode.com上#Haskell IRC频道,并提出问题.这些人绝对是新手友好的,并且随着时间的推移帮助了我很多.此外,就在这里SO是一个很好的地方,可以帮助你无法掌握的东西!尽量不要气馁,一旦点击,你的思绪就会被吹嘘.

BONUS的教程将为您提供帮助,让您为Real World Haskell带来的惊险刺激做好准备.祝你好运!


Jac*_*esB 12

如果您只有使用命令式/ OO语言的经验,我建议使用更传统的功能语言作为踏脚石.Haskell 真的与众不同,您必须了解许多不同的概念才能获得.我建议首先处理ML风格的语言(例如F#).


小智 10

第一个答案是非常好的答案.为了达到专家级别,您应该与一些专家自己一起攻读博士学位.

我建议你访问Haskell页面:http://haskell.org.在那里,您有很多材料,并且很多参考Haskell社区批准的Haskell中最新的东西.

  • 抱歉,但是在这里使用PhD参数就像是说您必须拥有300美元的厨刀才能成为好厨师。甚至Haskell的父亲Simon Peyton Jones也没有博士学位。实践和坚持不懈是导致在此领域和任何其他领域获得专业知识的原因。 (2认同)