[Haskell-cafe] Fwd: [Haskell-beginners] monad and variable result
Seph Shewell Brockway
seph at codex.scot
Tue Dec 11 19:27:21 UTC 2018
On Tue, Dec 11, 2018 at 04:54:24PM +0100, Damien Mattei wrote:
> but the question rest entire :how can i get the loat number from all this?
>
> i have a Main that looks like this:
>
>
> main :: IO ()
> --main :: Int
> main =
>
> do
> conn <- connect defaultConnectInfo
> { connectHost = "moita",
> connectUser = "mattei",
> connectPassword = "sidonie2",
> connectDatabase = "sidonie" }
>
>
>
> -- first we get the N°BD from sidonie
>
> let name = "A 20"
>
> let noBD_IO = getBD conn name
>
> -- putStrLn $ show $ read $ Text.unpack noBD_IO
>
> close conn
>
> print "Exit."
Within a do block, ‘let’ statements are for pure values, while
for monadic ones you bind a variable with <-, for example with
noBD <- getBD conn name
whatever
This is do-notation, which desugars to
getBD conn name >>= \noBD -> whatever
In this context, >>= has type signature
(>>=) :: IO a -> (a -> IO b) -> IO b
In fact it works for any monad, but let’s stick to IO for now. If we
look at this function type a bit, we see that it takes a monadic
computation and feeds it into a function that takes a _pure_ value.
In this case the function in question is your print statement:
putStrLn . show :: Show a => a -> IO ()
(There is actually a builtin function called print that does exactly
this.) Its input type is a, not IO a, so the result of getBD can’t be
used as-is, but >>= (pronounced ‘bind’) enables the return value of the
IO computation to be fed into the new function, returning a new monadic
computation representing the combination of the two original ones.
If you think about it, the ‘inescapable’ nature of the IO monad makes
sense: if a function is pure, it can’t have side effects, and therefore
it can’t use any data that it has to execute a side effect to get.
However, the fact that the main function has a monadic type IO (),
combined with the ability to ‘chain’ monadic computations as described
above, means that you don’t ever need to escape the IO monad; you can
simply ‘pull’ the pure functions you need _into_ the monad instead.
If I may make a suggestion, I would avoid using do-notation at all until
you’re a bit more comfortable with how monadic computations work, and
how Haskell handles IO. To someone used to imperative programming, it
can be more confusing that helpful, as it allows you to write something
that looks and feels a lot like imperative code but differs from it in
crucial ways. Get comfortable with using the monadic operators >> and >>=
directly, and only then switch back to do-notation. Or don’t—personally
I prefer not to use do-notation at all.
Regards,
Seph
--
Seph Shewell Brockway, BSc MSc (Glas.)
More information about the Haskell-Cafe
mailing list