真实世界Haskell的哪些部分现在已经过时或被认为是不好的做法?

真实世界Haskell的第19章中,很多例子现在都因为Control.Exception的改变而失败了。

这让我想,也许这本书中的一些东西实际上已经过时了,不值得再学习了,毕竟已经6年了。 我唯一的另一个参考是学习你一个Haskell为好 ,虽然这是一本很好的书,它是比RWH更基础。

任何读过这本书之前,请给出一些build议,哪些部分不再相关? 特别是本书后半部分的章节,如软件事务内存,并发编程,套接字编程等。

编辑:这是关于2008年12月出版的这本书的版本,这是今天唯一已知的版本(2017年11月)

RWH的主要问题

这是旧的。 RWH是在GHC的6.8版本被使用的时候编写的。 6.8使用的基本版本3.0.xx 6.10.1已经使用4.0.0.0,它引入了很多变化 。 这只是从6.8到6.10的跳跃。 GHC的当前版本是7.10。 Monads已经改变了。 目前有一个关于从Monad取消return的讨论,所以现实世界中的Monad实例Haskell实际上会与现实世界不同步。

这就是说,它仍然是一般准则的有用资源。 但请记住,自发布以来,许多库已经发生了变化。

阅读RWH时你可以一起阅读的内容是Stephen Diehl在“学习Haskell的时候我所知道的” 。 它提供了更多的见解,但请注意,有些章节并不真正适合新手。

一般评论

  • 阅读评论。 它们通常包含给定段落/部分是否仍然相关和/或正在工作的信息。
  • 阅读您要使用的库/函数的文档。 即使你是懒惰的,至less知道types。

对章节的评论

这只是我在阅读RWH时注意到的一些事物的快速概览。 这可能不完整。

第2章types和function与FTP

由于GHC 7.10

由于可折叠 – 可穿越build议 , nulltypes已经改变 。 许多其他的function,比如foldrfoldl以及之前在Prelude[a]定义的许多其他function,已被replace为更一般的Foldable t => ta变体。

第十一章testing和质量保证

自Haskell平台2010年或2008年底。

尽pipe在脚注中提到了QuickCheck库,但版本1在版本2中有很多变化。例如, generate现在使用Gen a而不是StdGen ,旧的generate的function在Test.QuickCheck.Gen.unGen

有疑问,请检查文档 。

第十四章单子和第十五章用单子编程

破解代码: Applicative m => Monad m

从GHC 7.10开始, Applicative现在是Monad的超类,这在2007年是没有计划的。

在GHC 7.10中, Applicative将成为Monad的超类,可能会破坏很多用户代码。 为了缓解这一转变,GHC现在会在定义与“申请单一提案”( AMP )冲突时产生警告。

见7.8.1发行说明 。

State / Writer / Reader单子

请问真正的国家monad请站起来吗? 部分,作者声称

为了定义Monad实例,我们必须提供适当的types构造函数以及(>>=)return定义。 这导致我们对State的真正的定义。

 -- file: ch14/State.hs newtype State sa = State runState :: s -> (a, s) } 

这不再是事实,因为State及其朋友现在通过实施

 type State s = StateT s Identity type Writer w = WriterT w Identity type Reader r = ReaderT r Identity 

所以他们是由他们的monad变压器来定义的。

第17章与C接口:FFI

整个章节是好的,但正如人们可以在评论或Yuras Shumovich的博客中看到的 ,下面代码中的终结器部分是不好的做法:

 pcre_ptr <- c_pcre_compile pattern (combineOptions flags) errptr erroffset nullPtr if pcre_ptr == nullPtr then do err <- peekCString =<< peek errptr return (Left err) else do reg <- newForeignPtr finalizerFree pcre_ptr -- release with free() return (Right (Regex reg str)) 

由于malloc()应该和free()一起使用, newdeletedeallocate ,应该总是使用正确的函数。

TL; DR您应该始终使用为您分配的相同分配器释放内存。

如果外部函数分配内存,则还应该使用随附的释放函数。

第19章error handling

error handling完全从6.8更改为6.10,但您已经注意到了。 更好地阅读文档 。

第22章扩展示例:Web客户机编程

有些例子似乎被打破了。 此外,还有其他HTTP库可用。

第25章分析和优化

一般的分析技术仍然是一样的,这个例子(见下文)是一个很好的案例研究,可以在您的程序中发生的问题。 但RWH缺lessmultithreading分析,例如通过ThreadScope。 而且,据我所知,懒惰的IO在整本书中都没有涉及。

 mean :: [Double] -> Double mean xs = sum xs / fromIntegral (length xs) 

第24章和第28章(并行和并行编程和STM)

虽然第24章并发和多核编程和第28章软件事务内存仍然是相关的,但Simon Marlow的书“ 并行和并行编程”只关注并发和并行编程,而且是最近的一次(2013年)。 RWH中完全没有GPU编程和修复。

第26章高级库devise:构build布隆filter

和其他章节一样,devise图书馆的总体指导方针仍然是写得很好,相关的。 但是,由于ST一些变化(?),结果不能再编译了。

第27章networking编程

它仍然是最新的。 毕竟,networking编程不会那么容易地改变。 但是,代码使用不推荐的函数bindSocketsClose ,应该用bindclose (最好通过限定的import)来replace。 请记住,它是非常低级的,你可能想要使用更专业的高级库。

附录A.安装GHC和Haskell库

GHC 6.8是Haskell平台推出之前的最后一个版本。 因此,附录告诉你手动获取GHC和Cabal。 别。 请按照haskell.org 下载页面上的说明进行操作。

另外,附录并没有告诉你关于Cabal沙盒的介绍, Cabal沙盒是在1.18版本中引入的,可以让你免于依赖地狱 。 当然, stack完全没有了。

内容丢失

RWH根本没有讨论过一些话题。 这包括stream媒体库,如pipe道和导pipe ,以及镜头 。

这些主题有几个资源,但是这里有一些介绍的链接给你一个想法是什么。 另外,如果你想使用vector,使用vectors包。

Control.Applicative

RWH在几个点使用Control.Applicative (<$>) ,但根本没有解释Control.Applicative 。 LYAH和Typeclassopedia包含Applicative部分。 鉴于ApplicativeMonad的超类(参见上文),build议您Monad学习。

此外, Control.Applicative (和types类本身)的几个运算符现在是Prelude一部分,因此请确保您的运算符不与<$><*>等冲突。

镜头

  • Edward Kmett的video ( lens作者)
  • Adam Gundry的video“镜头:构图数据访问和操作”
  • Jakub Arnold介绍和指导

stream媒体库

  • 导pipe概述作者Michael Snoyman ( conduit
  • 加布里埃尔·冈萨雷斯 ( pipes作者,包括在pipes包)

工装

  • Cabal版本1.18,引入了沙箱
  • stack是一个开发Haskell项目的跨平台程序
  • ghc-mod ,vim的后端,emacs,Sublime Text和其他编辑器

新/缺less语言扩展和GHC更改

  • 运行时types多态性( :i ($)已经发生了巨大的变化)
  • -XTypeInType
  • -XDataKinds
  • -XGADT
  • -XRankNTypes
  • -XGenericNewtypeDeriving
  • -XDeriveFunctor
  • 在6.6之后发生的任何其他扩展