Я рад что смог объяснить как правильно держать молоток. А то что любую задачу можно решить без комонад (так же как без стрелок (Arrow), без профункторов), то это конечно. Я привёл ссылку на «Gabriel Gonzalez,… комонады это объекты». Другие примеры с комонадами в статьях Клеточные автоматы с помощью комонад, Evaluating cellular automata is comonadic, Part I: From Theory to Pretty Pictures. Так что если Вы поняли как держать молоток — уже хорошо. Можно прочитать другие статьи. В последней Edward Kmett, заодно ссылается на свой пакет lens, где он использовал комонады.
Что значит «теряются» (если они вон используются в нескольких местах)
В смысле, что их не получить из списка [Figure], т.е. мы вынуждены реализовать все возможные действия как функции в Figure, т.е. объединяем хранение с логикой и представлением.
Возможно, статье лучше бы подошло название вроде «Эмуляция традиционного ООП на языке Haskell».
Мне кажется, что эмуляция — это, например, wiki.haskell.org/OOP_vs_type_classes, п.5. По классу типов на каждый тип данных.
То что у меня тоже сохраняются исходные данные и приходится использовать ExistentialQuantification — ну, не является оно абсолютным злом. По Вашей же ссылке: «Замыкания — это объекты для бедных!». Я, конечно, так не считаю, но название пока оставлю. Вставлю в начало статьи упоминание о приведённой ниже Вашей альтернативе.
Рад Вашему энтузиазму. (Без сарказма). Статью антипаттерн читал по ссылки с dev.stephendiehl.com/hask — это частное мнение, а не абсолют. То, что задачу можно решить разными способами, не сомневаюсь. И разные варианты имеют свои недостатки. Например, у Вас исходные координаты теряются, превращаясь сразу в строки. Конкретный пример решается, но, если потребуется координаты использовать разными способами, то станет посложнее (хотя, тоже решается). Я знаю и то что, в Haskell, вобщем то, не стОит применять ООП-шаблоны, а использовать Haskell-евские приёмы. Однако, есть тенденция — arxiv.org/pdf/cs/0509027v1.pdf
Кратко: у меня пример, демонстрирующий некоторые языковые расширения и использование классов типов. У Вас другой пример. Ничего не имею против. Поставлю лайк на Ваш ответ.
Допустим, диапазон задан 10… 20, а нужно добавить 1 к текущему номеру. 1 не в диапазоне, так что получится только через (+.). При этом контроль выхода результата за диапазон сохраняется. А сам Num нужен, см. пример с топливом.
В Haskell не обязательно использовать head. можно take 1 или Safe.headMay или Safe.headDef.
Да, даже Type-Level Literals предназначены, на самом деле, в первую очередь для compile-time контроля, этого самого dependent types dev.stephendiehl.com/hask/#typelevel-numbers. Это я их (и не только я) «нетрадиционно» использую.
К сожалению, в этом решении все константы должны быть известны на этапе компиляции, что сужает область применения.
Именно так и задумано.
Бывает, что границы известны заранее и это уменьшает затраты на хранение переменных границ.
Когда границы меняются динамически — см. вариант 1 в статье. Плюс контроль границ массивов и других контейнерных типов уже реализованный библиотечно.
Никаких сложностей в написании больших приложений на функциональных языках, и, в частности на Haskell, нет. И приложения большие есть.
Я думаю, Вы догадываетесь, что подобные вопросы не новы.
Относительно малая распространённость Haskell объясняется так называемым «большим порогом вхождения в язык». Т.е. нужно достаточно много из Haskell выучить прежде чем писать программы сложнее вычисления факториала. Зато потом пишется и отлаживается быстрее.
В смысле, что их не получить из списка [Figure], т.е. мы вынуждены реализовать все возможные действия как функции в Figure, т.е. объединяем хранение с логикой и представлением.
Мне кажется, что эмуляция — это, например, wiki.haskell.org/OOP_vs_type_classes, п.5. По классу типов на каждый тип данных.
То что у меня тоже сохраняются исходные данные и приходится использовать ExistentialQuantification — ну, не является оно абсолютным злом. По Вашей же ссылке: «Замыкания — это объекты для бедных!». Я, конечно, так не считаю, но название пока оставлю. Вставлю в начало статьи упоминание о приведённой ниже Вашей альтернативе.
Кратко: у меня пример, демонстрирующий некоторые языковые расширения и использование классов типов. У Вас другой пример. Ничего не имею против. Поставлю лайк на Ваш ответ.
Да, даже Type-Level Literals предназначены, на самом деле, в первую очередь для compile-time контроля, этого самого dependent types dev.stephendiehl.com/hask/#typelevel-numbers. Это я их (и не только я) «нетрадиционно» использую.
с Idris не знаком.
Бывает, что границы известны заранее и это уменьшает затраты на хранение переменных границ.
Когда границы меняются динамически — см. вариант 1 в статье. Плюс контроль границ массивов и других контейнерных типов уже реализованный библиотечно.
Насчёт Num' — согласен, перемудрил.
Я думаю, Вы догадываетесь, что подобные вопросы не новы.
Относительно малая распространённость Haskell объясняется так называемым «большим порогом вхождения в язык». Т.е. нужно достаточно много из Haskell выучить прежде чем писать программы сложнее вычисления факториала. Зато потом пишется и отлаживается быстрее.