Haskell入门

几天来,我试图围绕Haskell中的函数式编程范例进行研究。 我通过阅读教程和观看屏幕录像来完成这一任务,但似乎没有任何关系。 现在,在学习各种命令/ OO语言(如C,Java,PHP)时,练习对我来说是一个好方法。 但是由于我并不真正了解Haskell的能力,并且因为有许多新的概念需要使用,所以我不知道从哪里开始。

那么,你是如何学习Haskell的? 是什么让你真的“破冰”? 还有,开始练习的好主意?


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

绝对的新人

首先,haskell具备足够的技能是可以胜任的。 它非常快(根据我的经验,只有c和c ++),并且可以用于从仿真到服务器,guis和web应用程序的任何事情。

但是,有些问题比较容易为哈斯克尔的初学者编写。 数学问题和列表过程程序是很好的候选对象,因为它们只需要最基本的haskell知识即可编写。

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

另外两个好的资源是哈斯克尔编程的第一原则,以及哈斯克尔编程。 他们都为每章提供练习,所以你有一些简单的问题与你在前几页学到的东西相匹配。

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

一旦你完成了其中的一部分,你就可以继续做一些Project Euler问题。 这些是根据有多少人完成了他们,这是一个很好的迹象表明困难。 这些测试你的逻辑并比以前的问题更具价值,但你仍应该能够做到前几个。 haskell有一个很大的优势,就是整数的大小没有限制。 为了完成其中一些问题,阅读第7章和第8章学习Haskell将会很有用。

初学者

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

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

过了一会儿,你会看到第十四章,可怕的monads章节(dum dum dummmm)。 由于概念的抽象程度,几乎每个学习haskell的人都难以理解单子。 我无法想象另一种语言中的概念与函数式编程中的monad一样抽象。 Monads允许在一个想法下统一许多想法(例如IO操作,可能失败的计算,解析......)。 所以,如果在阅读monads章节后,你不会感到气馁,那么你就不会真正理解它们。 我发现阅读monads的许多不同解释是有用的; 每一个问题都给出了一个新的视角。 这是monad教程的一个很好的列表。 我强烈推荐Monads的所有内容,但其他人也很好。

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

为了确保您完全理解Haskell类型系统,您应该尝试解决20个中级Haskell练习。 这些练习使用了“毛茸茸”和“香蕉”等功能的有趣名称,并帮助您对一些基本的功能性编程概念有了很好的理解,如果您还没有这些概念的话。 不错的方式来度过你的晚上与箭头,独角兽,香肠和毛茸茸的香蕉的报纸列表。

中间

一旦你理解了Monads,我认为你已经从一个初学者的haskell程序员转变成了一个中间的haskeller。 那么从哪里去? 我会推荐的第一件事(如果你还没有从学习monads中学到它们的话)是各种类型的monads,比如Reader,Writer和State。 再次,真实世界haskell和所有关于monads给这个很好的报道。 要完成你的monad培训,了解monad变压器是必须的。 这些让你可以将不同类型的Monads(如Reader和State monad)合并为一个。 这看起来似乎毫无用处,但在使用它们一段时间之后,你会想知道你没有它们的生活。

如果你愿意,现在你可以完成真实世界的哈斯克尔书。 现在跳过章节并没有什么关系,只要你有单身男人。 只要选择你感兴趣的东西。

有了现在的知识,你应该能够使用cabal上的大部分软件包(以及至少有文档记载的软件包)以及大多数随Haskell提供的库。 一系列有趣的图书馆可以尝试:

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

  • Quickcheck:非常酷的测试程序。 你所做的是编写一个应该始终为真的谓词(例如length (reverse lst) == length lst )。 然后,您将谓词传递给quickCheck,并且它会生成很多随机值(在本例中为列表),并测试谓词对于所有结果是否为真。 另见在线手册。

  • HUnit:在haskell中进行单元测试。

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

  • happstack:haskell的web开发框架。 不使用数据库,而使用数据类型存储。 相当不错的文档(其他流行的框架将是快捷和yesod)。

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

  • 应用:像Monad这样的界面,但功能较弱。 每个Monad都适用,但反之亦然。 这是有用的,因为有些类型是Applicative但不是Monads。 此外,使用Applicative函数编写的代码通常比使用Monad函数编写等效代码更加可组合。 通过学习您的haskell指南,了解Functors,Applicative Functors和Monoid。

  • 可折叠,可穿透:抽象列表的许多操作的类型类,以便可以将相同的函数应用于其他容器类型。 另请参阅haskell wiki解释。

  • Monoid:Monoid是一个具有零(或空值)值的类型,并且有一个操作,注释<>将两个Monoid连接在一起,使得x <> mempty = mempty <> x = xx <> (y <> z) = (x <> y) <> z 。 这些被称为身份和结社性法律。 许多类型都是mempty = 0 ,例如数字, mempty = 0<> = + 。 这在很多情况下都很有用。

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

  • 数组:Haskell中的各种可变/不可变数组。

  • ST Monad:可让您编写具有可快速运行的可变状态的代码,同时在monad外部仍保持纯粹状态。 请参阅链接查看更多细节。

  • FRP:Functional Reactive Programming,一种编写处理事件,触发器,输入和输出(例如gui)的代码的新实验方法。 虽然我对此不太了解。 保罗胡达克关于薯条的谈话是一个好的开始。

  • 有很多新的语言功能你应该看看。 我将列出它们,你可以从谷歌,haskell wikibook,haskellwiki.org网站和ghc文档中找到关于它们的大量信息。

  • 多参数类型类/函数依赖关系
  • 类型家庭
  • 存在量化类型
  • 幻影类型
  • GADTS
  • 其他...
  • 许多haskell基于类别理论,因此您可能需要考虑这一点。 一个好的起点是计算机科学家的分类理论。 如果你不想购买这本书,作者的相关文章也非常出色。

    最后,你会想了解更多关于各种Haskell工具。 这些包括:

  • ghc(及其所有功能)
  • cabal:haskell包装系统
  • darcs:用haskell编写的分布式版本控制系统,在haskell程序中非常流行。
  • haddock:一个haskell自动文档生成器
  • 在学习所有这些新的库和概念的同时,在哈斯克尔编写一个中等规模的项目是非常有用的。 它可以是任何东西(例如小游戏,数据分析器,网站,编译器)。 在此基础上进行工作将允许您应用您正在学习的许多东西。 你留在这个层面很久了(这就是我所在的地方)。

    专家

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

    获得帮助

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

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

    那么这个结果比我预期的要长......无论如何,我认为这是一个非常好的主意,可以精通haskell。 这需要很长时间,但主要是因为你正在通过这样学习一种全新的思维方式。 它不像学习java之后学习ruby,而是喜欢学习java之后学习java。 另外,我发现面向对象的编程技巧由于学习haskell而得到了改进,因为我看到了许多抽象思路的新方法。


    我的一些同事在学习好你的Haskell方面有很好的经验!

    教程面向那些在命令式编程语言方面有经验的人员,但之前没有使用函数式语言进行编程。

    并在这里检查答案


    这里有一本你可以在网上阅读的好书:Real World Haskell

    我所做的大部分Haskell程序都是为了解决Project Euler问题。

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

    链接地址: http://www.djcxy.com/p/2283.html

    上一篇: Getting started with Haskell

    下一篇: Generate tail call opcode