I am trying to understand Monads in Haskell and during my countless experiments with code I have encountered this thing:
f2 = do
return \"da\"
When learning about monads it's helpful to expand them out manually yourself, for instance the simple example:
test0 :: IO String
test0 = do
a <- getLine
putStrLn a
return a
If we enable the language extension {-# LANGUAGE ScopedTypeVariables #-}
then we can annotate each of the lines in the monad with it's explicit type which will show the type of the return block.
{-# LANGUAGE ScopedTypeVariables #-}
test1 :: IO String
test1 = do
a <- getLine :: IO String
putStrLn a :: IO ()
return a :: IO String
We can also annotate the explicit type of the left hand side pattern matching which "extracts" from the monad context on the right hand side.
test2 :: IO String
test2 = do
(a :: String) <- getLine :: IO String
(() :: ()) <- putStrLn a :: IO ()
return a :: IO String
We can even expand out the do-notation into its constituting parts:
test3 :: IO String
test3 = getLine >>=
(\a -> putStrLn a >>=
\() -> return a)
Hope that helps build your monad intuition.