Габриэль Гонсалес написал в своем блоге прекрасную информацию о том, почему вы должны заботиться, и вы действительно должны заботиться. Вы можете прочитать его здесь (а также см. это).
Речь идет о масштабируемости, архитектуре и дизайне API. Идея в том, что есть «Традиционная архитектура», которая гласит:
Объедините вместе несколько компонентов типа A, чтобы создать «сеть» или «топологию» типа B.
Проблема с таким дизайном заключается в том, что по мере масштабирования вашей программы растет и ваш ад при рефакторинге.
Итак, вы хотите изменить модуль А, чтобы улучшить свой дизайн или домен, и вы это делаете. О, но теперь сломались модули B и C, зависящие от A. Вы исправляете B, отлично. Теперь вы исправляете C. Теперь B снова сломался, так как B также использовал некоторые функции C. И я могу продолжать это вечно, и если вы когда-либо использовали ООП, то и вы сможете.
Затем есть то, что Габриэль называет «архитектурой Haskell»:
Объедините вместе несколько компонентов типа A, чтобы создать новый компонент того же типа A, неотличимый по характеру от его замещающих частей.
Это тоже элегантно решает проблему. В основном: не наслаивайте свои модули и не расширяйте их, чтобы создавать специализированные.
Вместо этого комбинируйте.
Так что теперь поощряется то, что вместо того, чтобы говорить что-то вроде «У меня есть несколько X, поэтому давайте создадим тип, представляющий их объединение», вы говорите: «У меня есть несколько X, поэтому давайте объединим их в X». Или на простом английском: «Давайте в первую очередь сделаем составные типы». (ты уже чувствуешь, что моноиды прячутся?).
Представьте, что вы хотите создать форму для своей веб-страницы или приложения, и у вас есть модуль «Форма личной информации», который вы создали, потому что вам нужна была личная информация. Позже вы обнаружили, что вам также нужно «Изменить форму изображения», поэтому быстро написали это. А теперь вы говорите, что я хочу их объединить, поэтому давайте сделаем модуль «Личная информация и форма изображения». И в реальных масштабируемых приложениях это может выйти из-под контроля. Вероятно, не с формами, а для демонстрации, вам нужно сочинять и сочинять, чтобы в итоге вы получили «Личная информация и изменить изображение и изменить пароль и изменить статус и управлять друзьями и управлять списком желаний и изменять настройки просмотра и, пожалуйста, не расширяйте меня больше И пожалуйста, пожалуйста, остановитесь! И СТОП!!!!" модуль. Это некрасиво, и вам придется управлять этой сложностью в API. О, и если вы хотите что-то изменить - у него, вероятно, есть зависимости. Итак.. да.. Добро пожаловать в ад.
Теперь давайте посмотрим на другой вариант, но сначала давайте посмотрим на выгоду, потому что она приведет нас к ней:
Эти абстракции масштабируются безгранично, потому что они всегда сохраняют комбинируемость, поэтому нам никогда не нужно накладывать дополнительные абстракции сверху. Это одна из причин, почему вам следует изучать Haskell: вы узнаете, как создавать плоские архитектуры.
Звучит хорошо, так что вместо того, чтобы создавать модуль «Форма личной информации» / «Форма изменения изображения», остановитесь и подумайте, можем ли мы сделать что-нибудь здесь составным. Ну, мы можем просто сделать "Форму", верно? был бы также более абстрактным.
Тогда может иметь смысл создать один для всего, что вы хотите, объединить их вместе и получить одну форму, такую же, как и любую другую.
Итак, вы больше не получаете запутанное сложное дерево из-за ключа, что вы принимаете две формы и получаете одну форму. Таким образом, 1_. И, как вы уже ясно видите, эта подпись является экземпляром mappend
.
Альтернативная и обычная архитектура, вероятно, выглядели бы как a -> b -> c
, затем c -> d -> e
, а затем...
Теперь с формами все не так сложно; задача состоит в том, чтобы работать с этим в реальных приложениях. А для этого просто спросите себя как можно чаще (потому что это окупается, как видите): как я могу сделать эту концепцию компонуемой? и поскольку моноиды — это такой простой способ добиться этого (мы хотим простоты), сначала спросите себя: как эта концепция является моноидом?
Примечание: к счастью, Haskell очень сильно отговаривает вас от расширения типов, поскольку это функциональный язык (без наследования). Но еще можно сделать тип для чего-то, другой тип для чего-то, а в третьем типе иметь оба типа как поля. Если это для композиции — посмотрите, сможете ли вы этого избежать.
person
MasterMastic
schedule
07.10.2014
Data.Sequence
). Я уверен, что есть более простые примеры, которые я не могу сейчас придумать. - person luqui   schedule 07.10.2014