Весь смысл в том что делает bind - как написано собственно в комментариях он возьмёт функцию, которая должна возвращать списки, применит ко всех значением я соединим в один список.
Тут я только в примерах честно говоря теряюсь, было m a, а стало [a], не очень понятно... я до такого не доходил...
Разумеется, тут смысл в
bind, т. к. в моём примере только он и в ходу.
А вот
m a здесь это как раз и есть
[a], что можно записать более формально (язык поддерживает) как
[] a — в других языках это могло бы писаться
List a,
m = List. Видели параметризованные типы (а по-русски — generics) — вот монадами как раз могут быть только типы от одного параметра.
В хаскеле это, кстати, выразимо с помощью kinds — обычные типы имеют кинд
*, а тип с параметром кинда
k1, в результате применения которого получается тип кинда
k2, имеет кинд
k1 -> k2 — кинды для типов то же, что типы для значений. В некоторых языках идут дальше и определяют обобщение для всех натуральных, но хаскель ограничивается тремя уровнями. Так вот, с помощью некоторого расширения GHC можно было бы заголовок описания класса монады записать как
class Monad (m :: * -> *), явно указывая кинд, хотя обычно компилятор сам догадывается, потому что в функциях встречается только
m a.
[m..n], как уже сказал
_Ivana, это просто выражение типа
[a], если
m, n :: Enum a => a, т. е. типа, значения которого можно один за другим перечислять (а также через заданный шаг, для чего есть сахар
[m1,m2..n] и ещё два сахара
[m..] и
[m1,m2..] для бесконечных списков. Всё это синонимы вызовов некоторых методов
Enum, хотя тут для нас важно, что
Enum Int, и тип упомянутых выражений, соответственно, будет
[Int].
Ещё вижу кое-какую путаницу в основах, так что попробую их перечислить.
ведь если я (не)правильно понимаю Monad [] заставляет [] генерировать монаду списка, а что такое генератор списка от 1 и до монады мне вообще непонятно, всё, стоп машина мозговая
Monad, как и любой класс в хаскеле, скорее, аналогичен интерфейсам языков с ООП — он описывает
протокол, которому может удовлетворять какой-то набор типов (в частном случае, который у нас здесь, и который только и был в стандарте Haskell98, один тип; недавно в GHC появилось расширение, позволяющее нульарные классы, которым тоже находится применение). Чтобы указать, как и какой ещё набор удовлетворяет классу, пишется инстанс — в данном случае
Monad [] с определениями методов (не обязательно всех, т. к. могут быть определения по умолчанию, что сближает классы не просто с интерфейсами из ООП, а с примесями (mixins); так себя ведут интерфейсы Ceylon, например).
Имея на руках класс и набор инстансов из подключенных модулей, компилятор может заменить метод класса типа
Monad m => t m конкретным методом типа
t [] или там
t Maybe {здесь, кстати,
t не просто сокращение какого-то неизвестного выражения, но ещё и
:: (* -> *) -> *, но это уже можно счесть издевательством с моей стороны, так что скобки фигурные, и могли бы и не читать их} — во время ли выполнения или, при удаче (если программист достаточное количество конкретных типов прописал в других местах, обычно описывающих конкретные вещи), на этапе компиляции. Так что
Monad [] не «заставляет
[] генерировать монаду списка», тело инстанса
Monad [] описывает, как понимать список как монаду.
Некоторые люди считают всё-таки
[a] смущающим вариантом
List a (хотя я не соглашусь — если все смущающие совпадения удалить, получится непривычный мне вариант языка, так что невзвешенная оценка вполне уместна). В их варианте было бы
instance Monad List
return :: a -> List a
(>>=) :: List a -> (a -> List b) -> List b
и не было бы путаницы скобок с уровня значений со скобками с уровня типов (или нашлось бы что-то ещё не устраивающее).
А, и ещё: штучки вида
Class params или
(C1 ps1, C2 ps2, …) называются ограничениями (constraints) и могут пониматься как истинностные значения, знания о которых к нам приходят из и только из инстансов — либо в виде конкретных, в терминологии Пролога, фактов
C ps, либо в виде более изощрённых выводимостей
(C1 ps1, C2 ps2, …) => Cn psn, позволяющих в лучшем случае генерировать инстансы автоматически (а в худшем позволяющих компилятору завернуть ваш код, потому что это галиматья, и даже с расширениями иногда всё равно галиматья
). Соответственно, тип
Constraints => t состоит из тех же значений, что и
t, но только тех, для которых верны
Constraints. (КО приглашён на случай, если я переоценил чьи-то знания.)
-- Чт июн 11, 2015 00:34:47 --(Надеюсь, это что-то кому-то пояснило, а то я не уверен, что методически корректен.)