Какие части реального мира Haskell теперь устарели или считаются плохой практикой?

В главе 19 Real World Haskell многие примеры теперь терпят неудачу из-за изменения Control.Exception.

Это заставляет меня думать, что, может быть, некоторые вещи в этой книге на самом деле устарели и не стоят больше изучать, ведь прошло 6 лет. Моя единственная другая ссылка: Haskell For Great Good, хотя это отличная книга, она намного более простая по сравнению с RWH.

Может ли кто-нибудь, кто прочитал книгу, прежде чем давать какие-то советы, какие части ее больше не актуальны? Особенно главы во второй половине книги, например, транзакционная память программного обеспечения, параллельное программирование, программирование сокетов и т.д.

EDIT: речь идет о выпуске книги, опубликованной в декабре 2008 года, которая является единственным известным изданием на сегодняшний день (ноябрь 2017 года).

Ответ 1

Основная проблема RWH

Это старый. RWH был написан в то время, когда использовалась версия 6.8 GHC. 6.8 используется базовая версия 3.0.x.x. 6.10.1 уже используется 4.0.0.0, в котором было внесено много изменений. И это просто прыжок с 6,8 до 6,10. Текущая версия GHC - 7.10. Монады были изменены. В настоящее время обсуждается для удаления return из Monad, поэтому экземпляр Monad в Real World Haskell действительно будет не синхронизирован с в реальном мире.

Таким образом, это все еще полезный ресурс для общих руководящих принципов. Но имейте в виду, что многие библиотеки изменились с момента выпуска.

Что-то, что вы можете прочитать во время чтения RWH, "Что я хочу знать при изучении Haskell" Стивена Дила. Он дает дополнительную информацию, но имейте в виду, что некоторые разделы не очень дружелюбны для новичков.

Общие замечания

  • Прочитайте комментарии. Они обычно содержат информацию о том, все ли данный параграф/раздел по-прежнему актуальны и/или работают.
  • Прочитайте документацию о библиотеках/функциях, которые вы хотите использовать. Даже если вы ленивы, знаете, по крайней мере, типы.

Замечания к главам

Это просто краткий обзор некоторых вещей, которые я заметил при чтении RWH. Вероятно, он неполный.

Глава 2. Типы и функции и FTP

Так как GHC 7.10.

Тип null был изменен из-за Foldable-Traversable-Proposal. Многие другие функции, такие как foldr, foldl и многие другие, которые ранее были определены только для [a] в Prelude, были заменены более общими вариантами Foldable t => t a.

Глава 11. Тестирование и обеспечение качества

Так как Haskell-платформа 2010 или конец 2008 года.

Хотя это упоминается в footnote, библиотека QuickCheck во многом изменилась с версии 1 на версию 2. Например, generate теперь использует Gen a вместо StdGen, а функциональность старого generate находится в Test.QuickCheck.Gen.unGen.

В сомнении, проверьте документацию.

Глава 14. Монады и Глава 15. Программирование с монадами

Нарушение кода: Applicative m => Monad m

Начиная с GHC 7.10, Applicative теперь является суперклассом Monad, что не планировалось в 2007 году.

В GHC 7.10 Applicative станет суперклассом Monad, потенциально нарушившим много кода пользователя. Чтобы облегчить этот переход, GHC теперь генерирует предупреждения, когда определения конфликтуют с предложением Applicative-Monad (AMP).

См. 7.8.1 примечания к выпуску.

Монады State/Writer/Reader

В Будет ли реальная государственная монада встать?, авторы утверждают, что

Чтобы определить экземпляр 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

Таким образом, они определяются их трансформатором монады.

Глава 17. Взаимодействие с C: FFI

Общая глава в порядке, но, как можно читать в комментариях или на блоге Юраса Шумовича, часть финализатора в следующем коде плохая практика:

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. Расширенный пример: программирование веб-клиентов

Некоторые из примеров, похоже, сломаны. Кроме того, существуют и другие доступные библиотеки HTTP.

Глава 25. Профилирование и оптимизация

Общие методы профилирования все те же, и пример (см. ниже) является отличным примером для проблем, которые могут возникнуть в вашей программе. Но RWH отсутствует многопоточное профилирование, например. через ThreadScope. Насколько мне известно, ленивый IO не касается всей книги.

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

Глава 24 и Глава 28 (Параллельное и параллельное программирование и STM)

Пока Глава 24. Параллельное и многоядерное программирование и Глава 28. Программное обеспечение транзакционная память по-прежнему актуальны, книга Саймона Марлоу Параллельное и параллельное программирование в Haskell фокусируется исключительно на параллельном и параллельном программировании и довольно недавнее ( 2013). Программирование GPU и repa полностью отсутствуют в RWH.

Глава 26. Расширенный дизайн библиотеки: создание фильтра Bloom

Как и в других главах, общие рекомендации библиотеки дизайна все еще хорошо написаны и актуальны. Однако из-за некоторых изменений (?) Относительно ST результат больше не компилируется.

Глава 27. Сетевое программирование

Он по-прежнему в основном обновлен. В конце концов, сетевое программирование не так легко меняется. Однако в коде используются устаревшие функции bindSocket и sClose, которые должны быть заменены на bind и close (предпочтительно с помощью квалифицированного импорта). Имейте в виду, что он очень низкоуровневый, вы можете использовать более специализированную библиотеку высокого уровня.

Приложение A. Установка библиотек GHC и Haskell

GHC 6.8 была последней версией перед внедрением платформы Haskell. Поэтому в приложении говорится, что вы получите GHC и Cabal вручную. Не. Вместо этого следуйте инструкциям на странице haskell.org download.

Кроме того, в приложении не говорится о песочницах Cabal, которые были введены в Cabal 1.18 и освободили вас от адвентиля ада. И, конечно, stack отсутствует полностью.

Отсутствует контент

Некоторые темы вообще не обсуждаются в RWH. Это включает потоковые библиотеки, такие как pipes и conduit, а также объективы.

Есть несколько ресурсов для этих тем, но вот некоторые ссылки на интродукции, чтобы дать вам представление о том, о чем они. Кроме того, если вы хотите использовать векторы, используйте пакет vectors.

Control.Applicative

RWH использует Control.Applicative (<$>) в нескольких точках, но не объясняет Control.Applicative вообще. LYAH и Typeclassopedia содержат разделы на Applicative, Учитывая, что Applicative является суперклассом Monad (см. Выше), рекомендуется изучить этот класс наизусть.

Кроме того, несколько операторов Control.Applicative (и сам класс) теперь являются частью Prelude, поэтому убедитесь, что ваши операторы не сталкиваются с <$>, <*> и другими.

Объективы

Потоковые библиотеки

Инструменты

  • версия 1.18 Cabal, в которой представлены песочницы
  • stack, кросс-платформенная программа для разработки проектов Haskell.
  • ghc-mod, бэкенд для vim, emacs, Sublime Text и других редакторов

Новые/отсутствующие расширения языка и изменения GHC

  • Полиморфизм типа времени выполнения (:i ($) сильно изменился)
  • -XTypeInType
  • -XDataKinds
  • -XGADT
  • -XRankNTypes
  • -XGenericNewtypeDeriving
  • -XDeriveFunctor
  • любое другое расширение, которое произошло после 6.6