真实世界Haskell的哪些部分现在已经过时或被认为是不好的做法?
在真实世界Haskell的第19章中,由于Control.Exception
的更改,现在很多示例都失败了。
这让我想,也许这本书中的一些内容实际上已经过时,不值得再学习了,毕竟已经有6年了。 我唯一的另一个参考是学习你一个Haskell For Great Good,虽然它是一本很棒的书,但它比RWH更基础。
是否有人在阅读本书之前请给出一些建议,说明哪些部分不再相关? 特别是本书后半部分的章节,例如软件事务内存,并发编程,套接字编程等。
编辑:这是关于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
的讨论,所以Real World Haskell中的Monad
实例将会与真实世界脱节。
这就是说,它仍然是一般准则的有用资源。 但请记住,自发布以来,许多库都发生了变化。
在阅读RWH时,你可以一起阅读的内容是Stephen Diehl在“学习Haskell时想知道的事情”。 它提供了更多的见解,但请注意,有些章节并不真正适合新人。
一般评论
对章节的评论
这只是我在阅读RWH时注意到的一些事物的快速概览。 这可能不完整。
第2章类型和功能与FTP
由于GHC 7.10。
由于可折叠 - 可穿越建议, null
的类型已更改。 许多其他功能,例如foldr
, foldl
等许多以前仅在[a]
Prelude
[a]
中为[a]
定义的功能已被替换为更一般的Foldable t => ta
变体。
第十一章测试和质量保证
自Haskell平台2010或2008年末。
尽管在脚注中提到了这一点,但QuickCheck库在许多方面从版本1改变为版本2.例如,现在generate
使用Gen a
而不是StdGen
,而旧generate
的功能位于Test.QuickCheck.Gen.unGen
。
如有疑问,请查看文档。
第14章Monads和第15章用monad编程
破解代码: Applicative m => Monad m
从GHC 7.10开始, Applicative
现在是Monad
的超类,这在2007年是没有计划的。
在GHC 7.10中, Applicative
将成为Monad
的超类,可能会破坏很多用户代码。 为了缓解这种转变,GHC现在会在定义与“申请单一提案”(AMP)冲突时产生警告。
见7.8.1发行说明。
State
/ Writer
/ Reader
monads
Will的真实状态monad请站起来吗? 部分,作者声称
为了定义Monad
实例,我们必须提供适当的类型构造函数以及(>>=)
和return
定义。 这导致我们对State
的真正定义。
-- file: ch14/State.hs
newtype State s a = 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
, allocate
与deallocate
,每个人都应该使用正确的功能。
TL; DR您应该始终使用为您分配它的相同分配器释放内存。
如果外部函数分配内存,则还应该使用随附的释放函数。
第19章错误处理
错误处理完全从6.8更改为6.10,但您已经注意到了。 更好地阅读文档。
第22章扩展示例:Web客户机编程
有些例子似乎被破坏了。 此外,还有其他HTTP库可用。
第25章分析和优化
通用分析技术仍然是相同的,并且该示例(请参见下文)是您的程序中可能出现的问题的一个很好的案例研究。 但RWH缺少多线程分析,例如通过ThreadScope。 就我所知,懒惰的IO在整本书中并不关心。
mean :: [Double] -> Double
mean xs = sum xs / fromIntegral (length xs)
第24章和第28章(并行和并行编程和STM)
虽然第24章并发和多核编程和第28章软件事务内存仍然相关,但Simon Marlow的着作“Haskell中的并行和并行编程”仅着眼于并发和并行编程,并且是最近的一次(2013年)。 RWH中完全缺少GPU编程和修复。
第26章高级库设计:构建布隆过滤器
与其他章节一样,设计图书馆的总体指导方针仍然写得很好并且相关。 但是,由于ST
一些变化(?),结果不能再编译。
第27章网络编程
它仍然大部分是最新的。 毕竟,网络编程不会那么容易地改变。 但是,代码使用不推荐使用的函数bindSocket
和sClose
,应该使用bind
和close
(最好通过限定导入)替换它。 请记住,它是非常低级的,您可能想要使用更专业的高级库。
附录A.安装GHC和Haskell库
GHC 6.8是Haskell平台推出之前的最后一个版本。 因此,附录告诉你手动获取GHC和Cabal。 别。 请按照haskell.org下载页面上的说明进行操作。
另外,附录并没有告诉你关于Cabal沙箱的信息,Cabal沙箱是在Cabal 1.18中引入的,并且让你免于依赖地狱。 当然, stack
完全缺失。
内容丢失
RWH根本没有讨论一些话题。 这包括流媒体库,如管道和导管,以及镜头。
这些主题有几个资源,但是这里有一些介绍的链接,让你知道它们是什么。 另外,如果你想使用矢量,使用vectors
包。
Control.Applicative
RWH在几个点使用Control.Applicative
(<$>)
,但根本没有解释Control.Applicative
。 LYAH和Typeclassopedia包含Applicative
部分。 鉴于Applicative
是Monad
的超类(参见上文),建议您Monad
学习该类。
此外, Control.Applicative
(和类型类本身)的几个运算符现在是Prelude
一部分,因此请确保您的运算符不与<$>
, <*>
等冲突。
镜头
lens
作者) 流媒体库
conduit
作者) pipes
,包括在pipes
包) 工装
stack
,一个用于开发Haskell项目的跨平台程序 ghc-mod
,vim的后端,emacs,Sublime Text和其他编辑器 新/缺少语言扩展和GHC更改
:i ($)
已经发生了巨大变化) -XTypeInType
-XDataKinds
-XGADT
-XRankNTypes
-XGenericNewtypeDeriving
-XDeriveFunctor
上一篇: Which parts of Real World Haskell are now obsolete or considered bad practice?