Haskell入门

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

那么,你是如何学习Haskell的? 是什么让你真的“破冰”? 另外,任何好的想法开始练习?

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

绝对的新人

首先,哈斯克尔是有能力的,有足够的技巧。 这是非常快的(在我的经验中只有c和c ++),可以用于从模拟到服务器,guis和web应用程序的任何事情。

然而,在Haskell中有一些比其他人更容易编写的问题。 math问题和列表过程程序是很好的候选者,因为他们只需要最基本的haskell知识就能写出来。

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

另一个非常好的资源是从最初的原则的Haskell编程 。 它附带了每章的练习,所以你有一些简单的问题,匹配你在前几页学到的东西。

一个很好的问题列表是haskell 99问题页面 。 这些起点非常基本,随着你的继续变得更加困难。 做很多练习是非常好的练习,因为它们让你练习recursion和高阶函数的技巧。 我build议跳过任何需要随机性的问题,因为这在Haskell中有点困难。 如果您想使用QuickChecktesting您的解决scheme,请检查这个问题 (请参阅下面的中级 )。

一旦你做了一些这些,你可以继续做一些项目欧拉问题。 这些是根据有多less人完成的,这是一个相当不错的迹象。 这些testing你的逻辑和比以前的问题更多,但你应该能够做到前几个。 haskell有一个很大的优势,就是整数的大小没有限制。 为了完成其中一些问题,阅读第7章和第8章将会对你有所帮助。

初学者

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

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

过了一会儿,你会看到第十四章,可怕的monads章节(dum dum dummmm)。 由于概念的抽象性,几乎所有了解haskell的人都难以理解monad。 我想不出另一种语言的概念,就像函数式编程中的单子一样抽象。 Monads允许在一个想法下统一许多想法(例如IO操作,可能失败的计算,parsing…)。 所以,如果读完monad章后你不会感到灰心, 我发现阅读monads许多不同的解释是有用的。 每一个都给这个问题提供了一个新的视angular。 这是monad教程的一个很好的列表 。 我强烈推荐Monads ,但其他人也不错。

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

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

中间

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

如果你愿意,现在你可以完成现实世界的哈斯克尔书。 但是现在跳过章节并不重要,只要你有单身汉。 只要select你感兴趣的东西。

有了你现在的知识,你应该可以使用cabal上的大部分软件包(以及至less是有文档logging的软件包),以及Haskell附带的大多数库。 一个有趣的图书馆列表将尝试将是:

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

  • Quickcheck :非常酷的testing程序。 你所做的是写一个谓词,应该永远是真实的(例如length (reverse lst) == length lst )。 然后你传递谓词quickCheck,它会产生大量的随机值(在本例中是列表),并testing谓词对所有结果都是真实的。 另见在线手册 。

  • HUnit :unit testinghaskell。

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

  • happstack :一个用于haskell的web开发框架。 不使用数据库,而使用数据types存储。 相当不错的文档(另一个stream行的框架将是快照和yesod )。

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

  • 应用:像Monad这样的界面,但function较弱。 每个Monad是适用的,但不是相反的。 这是有用的,因为有一些types是适用的,但不是Monad。 此外,使用Applicative函数编写的代码通常比使用Monad函数编写等效代码更加可组合。 从学习你的haskell指南看Functors,Applicative Functors和Monoid 。

  • 可折叠 ,可遍历 :抽象列表的许多操作的typestypes,以便相同的function可以应用于其他容器types。 另请参阅haskell wiki解释 。

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

  • 箭头 :箭头是一种表示进行input并返回输出的计算的方式。 一个函数是最基本的箭头types,但也有很多其他的types。 该库也有许多非常有用的function来操纵箭头 – 即使只使用普通的旧的haskell函数,它们也是非常有用的。

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

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

  • FRP:function性react native编程(Functional Reactive Programming),一种编写处理事件,触发器,input和输出(如gui)的代码的新实验方法。 不过我对此并不了解。 保罗·胡达克(Paul Hudak)关于薯条的谈话是一个好的开始。

有很多新的语言function,你应该看看。 我将列出它们,你可以从谷歌, haskell wikibook,haskellwiki.org站点和ghc文档中find很多关于它们的信息。

  • 多参数types类/函数依赖
  • types家庭
  • 存在量化的types
  • 幻影types
  • GADTS
  • 其他…

许多haskell是基于类别理论的 ,所以你可能想看看。 计算机科学家的分类理论是一个很好的起点。 如果你不想买这本书,那么作者的相关文章也是非常好的。

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

  • ghc (及其所有function)
  • cabal :haskell包装系统
  • darcs :用haskell编写的分布式版本控制系统,在haskell程序中非常stream行。
  • haddock :一个haskell自动文档生成器

在学习所有这些新的库和概念的同时,在哈斯克尔编写一个中等规模的项目是非常有用的。 它可以是任何东西(例如小游戏,数据分析器,网站, 编译器 )。 在这个工作将允许你应用你正在学习的许多东西。 你留在这个层面很长时间(这是我在哪里)。

专家

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

获得帮助

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

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

结论

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

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

教程针对那些在命令式编程语言方面有经验的人员,但之前没有用function语言编程。

并在这里检查答案

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

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

我不久前读到的一条build议是,你应该有一套标准的问题,你知道如何解决(在理论上),然后当你试图学习一种新的语言,你用这种语言来实现这些问题。

我喜欢看这个使用Haskell进行函数式编程的13集系列。

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

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

命令行

安装好Haskell平台后,一定要cabal install hoogle

Hoogle使用示例:

你有一个函数fx = 3 * x + 1 ,你想在(5 :: Int)应用它,然后将其应用于结果和结果等等,并获得这些值的无限列表。 你怀疑可能已经有一个函数来帮助你(不是专门为你的f )。

如果需要5 f (我们假设函数为5 f a -> (a -> a) -> [a]那么函数的types是(a -> a) -> a -> [a]如果它需要f 5或者a -> (a -> a) -> [a]是一般的types而不只是Int s)

 $ hoogle "a -> (a -> a) -> [a]" Prelude iterate :: (a -> a) -> a -> [a] 

是的,你需要的function已经存在,它被称为iterate 。 你可以用iterate func 5使用它!

Web界面

同样的例子的结果可以在这里find。

Graham Hutton的Haskell编程简洁,合理,彻底,他Haskell多年的教学真正performance出来。 无论你从哪里出发,几乎总是我build议人们开始的。

特别是,第8章(“functionparsing器”)提供了开始处理单子时需要的真正基础,而且我认为这是迄今为止最好的开始,其次是“Monads” 。 (关于这一章,尽pipe如此,请注意网站上的勘误,但是, do没有特别的帮助,你不能使用do form,你可能想先学习typeclass并自己解决这个问题。

这对于Haskell初学者来说很less强调,但是值得学习相当早,不仅仅是关于使用monad,而是关于构build你自己的。 这并不难,定制的可以使许多任务变得更加简单。

不要试图用有趣的隐喻阅读所有的monad教程。 他们只会让你变得更糟。

我build议join#haskell irc频道并在那里提问。 我就是这么学习Haskell的。 如果你按照上面的build议经历真实世界的Haskell,那么对你的问题的实时回答将会有很大的帮助。 #haskell上的许多聪明人为了娱乐和写作而编写Haskell,所以你会得到很多好的input。 尝试一下!

这是我最喜欢的

Haskell:types的函数式编程

 Joeri van Eekelen, et al. | Wikibooks Published in 2012, 597 pages 

真实世界Haskell

  B. O'Sullivan, J. Goerzen, D. Stewart | OReilly Media, Inc. Published in 2008, 710 pages 

我还可以推荐另一个Haskell教程作为介绍。

Brent Yorgey的Typeclassopedia是另一个很好的学习资源(可能在中间层面),这对我来说帮了我很大的忙,而且在其他答案中没有提到,可以在Monad Reader中find13)

这是写在一个非常容易访问的风格,并包含(在许多其他事情),以下介绍的build议:

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

  1. 了解types。

  2. 深入了解每种types及其与其他types的关系,并通过熟悉许多示例来加以支持。

Monad Reader本身是function程序员(不仅是Haskell程序员)的绝对宝藏。

尝试编写简单的程序。

你可以在各种教科书中find示例任务。

我不build议坚持Haskell / FP的教科书,只是试图做一些简单的事情:计算,string操作,文件访问。

我解决了一打之后,我打破了冰冷的:)

之后,在高级概念(Monads,Arrows,IO,recursion数据结构)上阅读了很多,因为haskell是无限的,并且有很多。

我认为通过实例来实现Haskell的特性是首先要做的最好的方法。

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

这里是棘手的types包括monads和箭头

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

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

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

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

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

在Haskell_98_features和Typeclassopedia之后,我想你已经可以自己查找和阅读关于它们的文档

顺便说一下,您可能想要testing一些GHC的语言扩展,这可能是未来的haskell标准的一部分。

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

我build议你先阅读BONUS的教程 ,然后阅读Real World Haskell(免费在线) 。 joinirc.freenode.com上的#Haskell IRC频道 ,并提出问题。 这些人绝对是新手友好的,并且随着时间的推移帮了我很多。 此外,在这里,这是一个很好的地方获得帮助,你不能把握的东西! 尽量不要气馁,一旦点击,你的头脑将被吹。

奖金'教程将主宰你,让你准备好现实世界哈斯克尔带来的快感骑。 祝你好运!

如果你只有命令式/面向对象语言方面的经验,我build议使用更传统的function性语言作为踏脚石。 哈斯克尔是真的不同,你必须了解许多不同的概念,以获得任何地方。 我build议先解决一个ML风格的语言(如F#)。

第一个答案是非常好的。 为了达到专家水平,你应该和一些专家一起做博士学位。

我build议你访问Haskell页面: http : //haskell.org 。 在这里你有很多的资料,还有许多Haskell社区批准的Haskell中最新的东西的引用。