真实世界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议 , null
types已经改变 。 许多其他的function,比如foldr
, foldl
以及之前在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()
一起使用, new
的delete
和deallocate
,应该总是使用正确的函数。
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编程不会那么容易地改变。 但是,代码使用不推荐的函数bindSocket
和sClose
,应该用bind
和close
(最好通过限定的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
部分。 鉴于Applicative
是Monad
的超类(参见上文),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之后发生的任何其他扩展