web-dev-qa-db-fra.com

Quelles parties de Real World Haskell sont désormais obsolètes ou considérées comme de mauvaises pratiques?

Dans le chapitre 19 de Real World Haskell beaucoup d'exemples échouent maintenant en raison du changement de Control.Exception.

Cela me fait penser que certains des éléments de ce livre sont en réalité obsolètes et ne valent plus la peine d'être étudiés, après tout, cela fait 6 ans. Ma seule autre référence est Learn You a Haskell For Great Good, bien que ce soit un excellent livre, il est beaucoup plus basique que RWH.

Quiconque a déjà lu le livre peut-il donner des conseils sur les parties qui ne sont plus pertinentes? En particulier les chapitres de la seconde moitié du livre, par exemple, la mémoire transactionnelle logicielle, la programmation simultanée, la programmation de socket, etc.

EDIT: Il s'agit de l'édition du livre publiée en décembre 2008, qui est la seule édition connue à ce jour (novembre 2017)

104
swang

Numéro principal de RWH

C'est vieux. RWH a été écrit à un moment où la version 6.8 de GHC était utilisée. 6.8 utilisé la version de base 3.0.x.x. 6.10.1 déjà utilisé 4.0.0.0, qui a introduit beaucoup de changements . Et c'est juste le saut de 6,8 à 6,10. La version actuelle de GHC est 7.10. Les monades ont été changées. Il y a actuellement une discussion pour supprimer return de Monad , donc l'instance Monad dans Real World Haskell sera vraiment désynchronisée avec le monde réel .

Cela étant dit, c'est toujours une ressource utile pour les directives générales. Mais gardez à l'esprit que de nombreuses bibliothèques ont changé depuis sa sortie.

Quelque chose que vous pouvez lire en lisant RWH est "Ce que je souhaite que je sache en apprenant Haskell" par Stephen Diehl . Il fournit des informations supplémentaires, mais sachez que certaines sections ne sont pas vraiment adaptées aux nouveaux arrivants.

Remarques générales

  • Lisez les commentaires. Ils contiennent généralement des informations indiquant si le paragraphe/la section donnée est toujours pertinent et/ou fonctionne.
  • Lisez la documentation des bibliothèques/fonctions que vous souhaitez utiliser. Même si vous êtes paresseux, connaissez au moins les types.

Remarques sur les chapitres

Ce n'est qu'un bref aperçu de certaines des choses que j'ai remarquées en lisant RWH. C'est probablement incomplet.

Chapitre 2. Types et fonctions vs FTP

Depuis GHC 7.10.

Le type de null a été changé en raison de Foldable-Traversable-Proposition . De nombreuses autres fonctions telles que foldr, foldl et bien d'autres qui n'étaient auparavant définies que pour [a] Dans le Prelude ont été remplacées par un plus général Foldable t => t a Variantes.

Chapitre 11. Essais et assurance qualité

Depuis la plateforme Haskell 2010 ou fin 2008.

Bien que cela soit mentionné dans un note de bas de page , la bibliothèque QuickCheck a changé à bien des égards de la version 1 à la version 2. Par exemple, generate utilise maintenant Gen a Au lieu de StdGen, et la fonctionnalité de l'ancien generate est dans Test.QuickCheck.Gen.unGen.

En cas de doute, vérifiez la documentation .

Chapitre 14. Monades & Chapitre 15. Programmation avec des monades

Rupture de code: Applicative m => Monad m

Depuis GHC 7.10, Applicative est maintenant une superclasse de Monad, ce qui n'était pas prévu en 2007.

Dans GHC 7.10, Applicative deviendra une superclasse de Monad, cassant potentiellement beaucoup de code utilisateur. Pour faciliter cette transition, GHC génère désormais des avertissements lorsque les définitions entrent en conflit avec la proposition Applicative-Monad ( AMP ).

Voir Notes de version 7.8.1 .

Les monades State/Writer/Reader

Dans la section Est-ce que la véritable monade de l'État se lèvera? , les auteurs affirment

Afin de définir une instance Monad, nous devons fournir un constructeur de type approprié ainsi que des définitions pour (>>=) Et return. Cela nous amène à la vraie définition de State.

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

Ce n'est plus vrai, car State et ses amis sont désormais implémentés via

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

Ils sont donc définis par leur transformateur monade.

Chapitre 17. Interfaçage avec C: le FFI

Le chapitre général est bien, mais comme on peut le lire dans les commentaires ou sur le blog de Yuras Shumovich , la partie finalizer dans le code suivant est une mauvaise pratique:

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))

Comme malloc() doit être utilisé avec free(), new avec delete, allocate avec deallocate, on devrait utilisez toujours la fonction correcte.

TL; DR Vous devez toujours libérer de la mémoire avec le même allocateur qui vous l'a alloué.

Si une fonction étrangère alloue de la mémoire, vous devez également utiliser la fonction de désallocation qui l'accompagne.

Chapitre 19. Gestion des erreurs

La gestion des erreurs a complètement changé de 6,8 à 6,10, mais vous l'avez déjà remarqué. Mieux lire la documentation .

Chapitre 22. Exemple étendu: programmation client Web

Certains exemples semblent rompus. De plus, d'autres bibliothèques HTTP sont disponibles.

Chapitre 25. Profilage et optimisation

Les techniques générales de profilage sont toujours les mêmes, et l'exemple (voir ci-dessous) est une excellente étude de cas pour les problèmes qui peuvent survenir dans votre programme. Mais RWH manque de profilage multi-thread, par exemple via ThreadScope. De plus, paresseux IO n'est pas concerné dans tout le livre, pour autant que je sache.

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

Chapitre 24 & Chapitre 28 (Programmation simultanée et parallèle & STM)

Alors que Chapitre 24. Programmation simultanée et multicœur et Chapitre 28. Mémoire transactionnelle logicielle sont toujours pertinents, le livre de Simon Marlow Programmation parallèle et simultanée dans Haskell se concentre uniquement sur la programmation simultanée et parallèle et est assez récent (2013). La programmation GPU et le repa sont complètement absents dans RWH.

Chapitre 26. Conception de bibliothèque avancée: création d'un filtre Bloom

Comme pour les autres chapitres, les directives générales de la bibliothèque de conception sont toujours bien écrites et pertinentes. Cependant, en raison de quelques modifications (?) Concernant ST, le résultat ne peut plus être compilé.

Chapitre 27. Programmation réseau

Il est encore principalement à jour. Après tout, la programmation réseau ne change pas si facilement. Cependant, le code utilise les fonctions obsolètes bindSocket et sClose, qui doivent être remplacées par bind et close (de préférence via l'importation qualifiée). Gardez à l'esprit que c'est très bas niveau, vous voudrez peut-être utiliser une bibliothèque de haut niveau plus spécialisée.

Annexe A. Installation des bibliothèques GHC et Haskell

GHC 6.8 était la dernière version avant l'introduction de la plate-forme Haskell. Par conséquent, l'annexe vous indique d'obtenir GHC et Cabal à la main. Non. Suivez plutôt les instructions sur haskell.org page de téléchargement .

De plus, l'annexe ne vous parle pas des bacs à sable Cabal, qui ont été introduits dans Cabal 1.18 et vous libèrent de l'enfer des dépendances . Et bien sûr, stack est complètement manquant.

Contenu manquant

Certains sujets ne sont pas du tout abordés dans RWH. Cela inclut les bibliothèques de streaming telles que pipes et conduit , et aussi lentilles .

Il existe plusieurs ressources pour ces sujets, mais voici quelques liens vers des introductions pour vous donner une idée de leur sujet. De plus, si vous souhaitez utiliser des vecteurs, utilisez le package vectors .

Control.Applicative

RWH utilise le Control.Applicative De (<$>) À plusieurs reprises, mais n'explique pas du tout Control.Applicative. LYAH et le Typeclassopedia contiennent des sections sur Applicative. Étant donné que Applicative est une superclasse de Monad (voir ci-dessus), il est recommandé d'apprendre cette classe par cœur.

De plus, plusieurs opérateurs de Control.Applicative (Et la classe de caractères elle-même) font désormais partie de Prelude, alors assurez-vous que vos opérateurs ne se heurtent pas à <$>, <*> Et autres.

Verres

Bibliothèques en streaming

Outillage

  • la version 1.18 de Cabal, qui a introduit bacs à sable
  • stack , un programme multiplateforme pour développer des projets Haskell
  • ghc-mod , un backend pour vim, emacs, Sublime Text et autres éditeurs

Extensions de langage et modifications GHC nouvelles/manquantes

  • polymorphisme de type runtime (:i ($) a énormément changé)
  • -XTypeInType
  • -XDataKinds
  • -XGADT
  • -XRankNTypes
  • -XGenericNewtypeDeriving
  • -XDeriveFunctor
  • toute autre extension survenue après 6.6
133
Zeta