In the chapter 19 of Real World Haskell a lot of the examples now fail due to the change of Control.Exception
.
That makes me think maybe some of the stuff in this book is actually obsolete and not worth studying anymore, after all it's been 6 years. My only other reference is Learn You a Haskell For Great Good, though it's a great book, it's much more basic compared with RWH.
Can anyone who have read the book before please give some advice on which parts of it are no longer relevant? Especially the chapters in the second half of the book, for example, software transactional memory, concurrent programming, socket programming, etc.
EDIT: This is about the edition of the book that's published on Dec 2008, which is the only known edition as of today (Nov 2017)
It's old. RWH was written at a time version 6.8 of GHC was being used. 6.8 used base version 3.0.x.x. 6.10.1 already used 4.0.0.0, which introduced many changes. And that's just the jump from 6.8 to 6.10. The current version of GHC is 7.10. Monads have been changed. There's currently a discussion to remove return
from Monad
, so the Monad
instance in Real World Haskell will really be out of sync with the real world.
That being said, it's still a useful resource for general guidelines. But keep in mind that many libraries changed since its release.
Something you can read along while reading RWH is "What I Wish I Knew When Learning Haskell" by Stephen Diehl. It provides additional insight, but be aware, some sections aren't really newcomer friendly.
This is just a quick overview of some of the things that I noticed while reading RWH. It's probably incomplete.
Since GHC 7.10.
The type of null
has been changed due to the Foldable-Traversable-Proposal. Many other functions such as foldr
, foldl
and many other that were previously only defined for [a]
in the Prelude
have been replaced with more general Foldable t => t a
variants.
Since Haskell-platform 2010 or late 2008.
Although this is mentioned in a footnote, the QuickCheck library has changed in many ways from version 1 to version 2. For example, generate
now uses Gen a
instead of StdGen
, and the functionality of the old generate
is in Test.QuickCheck.Gen.unGen
.
In doubt, check the documentation.
Applicative m => Monad m
As of GHC 7.10, Applicative
is now a superclass of Monad
, something that wasn't planned in 2007.
In GHC 7.10,
Applicative
will become a superclass ofMonad
, potentially breaking a lot of user code. To ease this transition, GHC now generates warnings when definitions conflict with the Applicative-Monad Proposal (AMP).
See 7.8.1 release notes.
State
/Writer
/Reader
monadsIn the Will the real state monad please stand up? section, the authors claim
In order to define a
Monad
instance, we have to provide a proper type constructor as well as definitions for(>>=)
andreturn
. This leads us to the real definition ofState
.-- file: ch14/State.hs newtype State s a = State runState :: s -> (a, s) }
That's no longer true, because State
and its friends are now implemented via
type State s = StateT s Identity type Writer w = WriterT w Identity type Reader r = ReaderT r Identity
So they're defined by their monad transformer.
The overall chapter is fine, but as one can read in the comments or on Yuras Shumovich's blog, the finalizer part in the following code is bad practise:
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))
As malloc()
should be used with free()
, new
with delete
, allocate
with deallocate
, one should always use the correct function.
TL;DR You should always free memory with the same allocator that allocated it for you.
If a foreign function allocates memory, you should also use the accompanying deallocation function.
Error handling changed completely from 6.8 to 6.10, but you noticed that already. Better read the documentation.
Some of the example seem to be broken. Also, there are other HTTP libraries available.
General profiling techniques are still the same, and the example (see below) is a great case study for problems that can occur in your program. But RWH is missing multi-threaded profiling, e.g. via ThreadScope. Also, lazy IO isn't concerned throughout the whole book, as far as I know.
mean :: [Double] -> Double mean xs = sum xs / fromIntegral (length xs)
While Chapter 24. Concurrent and multicore programming and Chapter 28. Software transactional memory are still relevant, Simon Marlow's book Parallel and Concurrent Programming in Haskell focuses solely on concurrent and parallel programming and is pretty recent (2013). GPU programming and repa are completely missing in RWH.
As with the other chapters, the general guidelines of the design library is still well written and relevant. However, due to some changes (?) concerning ST
, the result cannot be compiled anymore.
It's still mostly up to date. After all, network programming doesn't change so easily. However, the code uses deprecated functions bindSocket
and sClose
, which should be replaced by bind
and close
(preferably via qualified import). Keep in mind that it's very low-level, you might want to use a more specialized high-level library.
GHC 6.8 was the last version before the Haskell Platform has been introduced. Therefore, the appendix tells you to get GHC and Cabal by hand. Don't. Instead, follow the instructions on the haskell.org download page.
Also, the appendix doesn't tell you about Cabal sandboxes, which were introduced in Cabal 1.18 and free you from dependency hell. And of course, stack
is missing completely.
Some topics are not discussed in RWH at all. This includes streaming libraries such as pipes and conduit, and also lenses.
There are several resources out there for those topics, but here are some links to introductions to give you an idea what they're about. Also, if you want to use vectors, use the vectors
package.
Control.Applicative
RWH uses Control.Applicative
's (<$>)
at several points, but doesn't explain Control.Applicative
at all. LYAH and the Typeclassopedia contain sections on Applicative
. Given that Applicative
is a superclass of Monad
(see above), it's recommended to learn that class by heart.
Furthermore, several operators of Control.Applicative
(and the typeclass itself) are now part of the Prelude
, so make sure that your operators don't clash with <$>
, <*>
and others.
lens
)conduit
)pipes
, included in the pipes
package)stack
, a cross-platform program for developing Haskell projectsghc-mod
, a backend for vim, emacs, Sublime Text and other editors:i ($)
has changed tremendously)-XTypeInType
-XDataKinds
-XGADT
-XRankNTypes
-XGenericNewtypeDeriving
-XDeriveFunctor
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With