SHOW:
|
|
- or go back to the newest paste.
| 1 | --Есть: | |
| 2 | f x = x * x --функция | |
| 3 | ||
| 4 | --Есть: | |
| 5 | - | f' () = M >> f(readFromFile) --монада? |
| 5 | + | f () = M >> f(readFromFile) --монада? |
| 6 | - | --что значит ()? Нет, у монады простое имя вроде f' или m |
| 6 | + | --что значит ()? |
| 7 | --что такое М? | |
| 8 | --Далее: f от readFromFile? Но readFromFile это не значение, а монада. | |
| 9 | --А функция f хочет значение, она не принимает монаду. | |
| 10 | --Оператор >> пригодился бы нам, если бы тут были две монады. Но монада одна - readFromFile. | |
| 11 | --И тут из тени появляется оператор >>=, который как раз _связывает_монаду_и_функцию_. | |
| 12 | ||
| 13 | m = do | |
| 14 | - | varX <- readFromFile |
| 14 | + | varX <- readFromFile --"получаем значение" |
| 15 | - | return (f x) |
| 15 | + | return (f x) --делаем новую монаду(return) с f от полученного значения |
| 16 | ||
| 17 | --так выглядит последовательность действий в do-нотации. Что там под капотом? Надо помнить что '<-' --это синтаксический сахар над >>= | |
| 18 | --Раскрывается это в следующее: | |
| 19 | ||
| 20 | m = readFromFile >>= (\varX -> return (f x)) | |
| 21 | --или | |
| 22 | m = readFromFile >>= return . f | |
| 23 | --дело в том, что >>= соеденяет монаду и функцию, но не абы какую функцию, а монадическую функцию. | |
| 24 | --Как сделать простую функцию монадической? Применить к результату return. | |
| 25 | --Можно воспользоваться лямбдой, а можно использовать комбинатор. | |
| 26 | --При этом 'a -> b' превращается в 'Monad m => a -> m b', | |
| 27 | --т.е монадическую функцию, которую и хочет оператор >>= вторым аргументом. | |
| 28 | ||
| 29 | --Надо отметить что IO это ещё и функтор, и операцию можно сократить до: | |
| 30 | m = fmap f readFromFile | |
| 31 | --но это уже другая история. | |
| 32 | ||
| 33 | --В итоге получилась монада m, которая содержит полученное из файла и умноженное на себя значение. |