LINUX.ORG.RU

История изменений

Исправление Macil, (текущая версия) :

Вот я и спрашиваю — где?

Знамо где. В рантайме, который совсем-совсем не чистый, и написан на C.

Если про Monad — то, как я уже писал, внутри µ. Только чистого µ как такового нет.

Наверное, основная причина непонимания работы Monad лежит в том, что когда начинающие смотрят на (>>=) :: m a → (a ­→ m b) ­→ m b, то думают что результирующий m b делает левая часть (f :: a → m b т.е.), а bind ee просто возвращает, но на самом деле, результирующий m b делает именно bind. Т.е. запускает некий runFoo :: m a → a для левой части, затем в зависимости от результата передает полученное значение в свою левую часть, еще раз запускает runFoo и оборачивает полученное значение в m через какой-то из комбинаторов a ­→ m b (не обязательно return). Если один из bind в цепочке не будет вычислять свою левую часть, то цепочка вычислений прервется.

Цепочка вычислений, она не совсем цепочка. Как и список, она напоминает луковицу (a >>= (\a' → b >>= (\b' → c >>= (\c' → ...)))), где bind сдирает очередной слой. Собственно, do-нотация и есть просто удобная запись вышеприведенного.

Можно придумать хитрый комбинатор, который будет противоположен bind, т.е. вычислять свою левую часть, когда bind ее не вычисляет. С помощью него можно организовать «обработку исключений».

Можно пойти дальше, и в качестве a использовать функцию... Что дает много интересных эффектов. Например, можно организовать несколько «точек выхода» http://www.scs.stanford.edu/11au-cs240h/notes/parsing-slides.html

PS: И да, бытует мнение что runIO не существует. Это мнение неправильное. Если он недоступен, как и конструктор IO, это не значит что его нет.

Исходная версия Macil, :

Вот я и спрашиваю — где?

Знамо где. В рантайме, который совсем-совсем не чистый, и написан на C.

Если про Monad — то, как я уже писал, внутри µ. Только чистого µ как такового нет.

Наверное, основная причина непонимания работы Monad лежит в том, что когда начинающие смотрят на (>>=) :: m a → (a ­→ m b) ­→ m b, то думают что результирующий m b делает левая часть (f :: a → m b т.е.), а bind ee просто возвращает, но на самом деле, результирующий m b делает именно bind. Т.е. запускает некий runFoo :: m a → a для левой части, затем в зависимости от результата передает полученное значение в свою левую часть, еще раз запускает runFoo и оборачивает полученное значение в m через какой-то из комбинаторов a ­→ m b (не обязательно return). Если один из bind в цепочке не будет вычислять свою левую часть, то цепочка вычислений прервется.

Цепочка вычислений, она не совсем цепочка. Как и список, она напоминает луковицу (a >>= (\a' → b >>= (\b' → c >>= (\c → ...)))), где bind сдирает очередной слой. Собственно, do-нотация и есть просто удобная запись вышеприведенного.

Можно придумать хитрый комбинатор, который будет противоположен bind, т.е. вычислять свою левую часть, когда bind ее не вычисляет. С помощью него можно организовать «обработку исключений».

Можно пойти дальше, и в качестве a использовать функцию... Что дает много интересных эффектов. Например, можно организовать несколько «точек выхода» http://www.scs.stanford.edu/11au-cs240h/notes/parsing-slides.html

PS: И да, бытует мнение что runIO не существует. Это мнение неправильное. Если он недоступен, как и конструктор IO, это не значит что его нет.