Я постепенно изучал Haskell и даже чувствую, что у меня есть подвешивание монад. Однако существует все еще много более экзотического материала, который я едва понимаю, как Стрелки, Применимые, и т.д. Хотя я поднимаю остатки из кода Haskell, я видел, было бы хорошо найти учебное руководство, которое действительно объясняет их полностью. (На монадах, кажется, существуют десятки учебных руководств.. но все, кажется, заканчивается прямо после этого!)
Вот несколько ресурсов, которые я нашел полезными после "освоения" монад:
Самое главное, покопайтесь в коде любых библиотек Hackage, которые вы используете.Если они делают что-то с синтаксисом, идиомами или расширениями, которых вы не понимаете, поищите это.
Типовые классы, такие как Monad
, Applicative
, Arrow
, Functor
- это здорово и все такое, и даже более здорово для изменения того, как вы думаете о коде, чем просто удобство наличия общих функций над ними. Но существует распространенное заблуждение, что "следующий шаг" в Haskell - это изучение большего количества классов типов и способов структурирования потока управления. Следующий шаг - это решить, что вы хотите написать, и попытаться написать это, изучая по пути то, что вам нужно.
И даже если вы поняли монады, это не значит, что вы поцарапали поверхность того, что можно сделать с монадически структурированным кодом. Поиграйте с библиотеками синтаксических комбинаторов или напишите свою собственную. Исследуйте, почему аппликативная нотация иногда проще для них. Исследуйте, почему ограничение себя аппликативными синтаксическими анализаторами может быть более эффективным.
Рассмотрите логические или математические задачи и изучите способы реализации обратного пути - в глубину, в ширину и т.д. Изучите разницу между ListT, LogicT и ChoiceT. Рассмотрите продолжения.
Или сделайте что-то совершенно другое!
Что касается классов типов:
Applicative
на самом деле проще, чем Monad
. Я недавно говорил несколько вещей об этом в другом месте, но суть в том, что это о расширенных Functor
, в которые вы можете поднимать функции. Чтобы почувствовать Applicative
, вы можете попробовать написать что-нибудь, используя Parsec без использования do
нотации- мой опыт показывает, что прикладной стиль работает лучше, чем монадический для простых парсеров.
Стрелки
- это очень абстрактный способ работы с вещами, которые похожи на функции ("стрелки" между типами). В них бывает трудно разобраться, пока не наткнешься на что-то, что естественным образом напоминает
Arrow
-функции. В свое время я изобрел половину Control.Arrow
(неудачно), когда писал интерактивные машины состояний с петлями обратной связи.
Вы не упомянули его, но часто недооцениваемый, мощный класс типов - это скромный Monoid
. Есть много мест, где можно найти моноидоподобную структуру. Посмотрите, например, на пакет monoids.
Помимо классов типов, я бы предложил очень простой ответ на ваш вопрос: Пишите программы! Лучший способ научиться - это делать, поэтому выберите что-нибудь интересное или полезное и просто сделайте это.
На самом деле, многие из более абстрактных понятий - например, Стрелка
- вероятно, будут иметь больше смысла, если вы вернетесь к ним позже и обнаружите, что, как и я, они предлагают аккуратное решение проблемы, с которой вы столкнулись, но даже не подозревали, что от нее можно абстрагироваться.
Однако, если вам нужно что-то конкретное, то почему бы не взглянуть на Функционально-реактивное программирование - это семейство методов, которые подают большие надежды, но есть много открытых вопросов о том, как лучше всего это сделать.
Далеко не самое важное, что вы можете сделать, - это больше изучать Hackage. Знакомство с различными экзотическими особенностями Haskell, возможно, позволит вам найти улучшенные решения некоторых проблем, а библиотеки на Hackage значительно расширят ваш набор инструментов.
Самое лучшее в экосистеме Haskell - это то, что вы можете сочетать изучение хирургически точных новых методов абстракции с изучением того, как использовать гигантские пилы, доступные вам на Hackage.
Вы знаете все, что вам нужно, чтобы идти и писать код. Но если вы хотите узнать больше о Хаскеле, могу предложить:
data TTrue = TTrue
data FFalse = FFalse
class TypeLevelIf tf a b where тип If tf a b weirdIfStatement :: tf -> a -> b -> tf a b
instance TypeLevelIf TTrue a b where тип If TTrue a b = a weirdIfStatement TTrue a b = a
instance TypeLevelIf FFalse a b where тип If FFalse a b = b weirdIfStatement FFalse a b = a
Это дает вам функцию, которая ведет себя как оператор if
, но может возвращать различные типы на основе истинностного значения, которое ей дано.
Если вам интересно программирование на уровне типов, то семейства типов предоставляют один из путей к изучению этой темы.
Шаблонный Хаскель. Это огромная тема. Она дает вам возможности, схожие с макросами в C, но с гораздо большей безопасностью типов.
Узнайте о некоторых ведущих библиотеках Haskell. Я не могу сосчитать, сколько раз parsec позволял мне быстро написать безумно полезную утилиту. dons периодически публикует список популярных библиотек на hackage; посмотрите его.
В качестве одного следующего шага (а не полудюжины "следующих шагов") я предлагаю вам научиться писать свои собственные классы типов. Вот пара простых задач для начала:
Написание некоторых интересных объявлений экземпляров для QuickCheck. Скажем, например, вы хотите генерировать случайные деревья, которые в некотором роде "интересны".
Перейдите к следующей небольшой задаче: определите функции /\
, \/
и complement
("and", "or", & "not"), которые можно применять не только к булевым числам, но и к предикатам произвольной степени. (Если вы внимательно посмотрите, то сможете найти ответ на этот вопрос на SO.)
Начать писать код. Вы узнаете необходимые концепции по ходу дела.
Помимо языка, чтобы эффективно использовать Haskell, вам необходимо изучить некоторые реальные инструменты и методы. На что следует обратить внимание:
*) cabal-init помогает быстро начать работу.
**) В настоящее время моим любимым инструментом для привязок FFI является bindings-DSL .