P
class Functor f where
fmap :: (a -> b) -> f a -> f b -- map
class Functor f => Applicative f where
pure :: a -> f a
...
class Applicative m => Monad m where
bind :: m a -> (a -> m b) -> m b -- добавить коллбэк
И есть do-синтаксис
main :: IO ()
main = do
putStrLn "Name?"
name <- getLine
putStrLn ("Hello, " ++ name ++ "!")
который разворачивается в
main =
bind (putStrLn "Name?") (\_ ->
bind getLine (\name ->
putStrLn ("Hello, " ++ name ++ "!")))
Что весьма напоминает
let main =
putStrLn("Name?").then(_ =>
getLine().then(name =>
putStrLn("Hello, " + name + "!")))
И почти оно же
async function main() {
await putStrLn("Name?")
let name = await getLine()
putStrLn("Hello, " + name + "!")
}
Так что промисы это вполне себе монады.
Монада - это наличие метода bind/then/flatMap, принимающих коллбэк, реаширующий на результат