Consider the following valid Haskell code
module Main where
main :: IO ()
main = do
let x = f
print x
f :: Maybe (Int, Int)
f =
Just 3 >>= (\a ->
Just 5 >>= (\b ->
return (a, b)))
where the function f
can be rewritten equivalently with do-notation like this
f :: Maybe (Int, Int)
f = do
a <- Just 3
b <- Just 5
return (a, b)
What annoys me, the do notation won't work when I put the contents of f
inline. The following code does not even parse:
main :: IO ()
main = do
let x = do
a <- Just 3
b <- Just 5
return (a, b)
print x
Am I correct that inside let
I am forced to resort to (>>=)
?
While I'm at it, the following code does not parse, either:
module Main where
main :: IO ()
main = do
let x =
Just 3 >>= (\a ->
Just 5 >>= (\b ->
return (a, b)))
print x
I don't see an obvious reason other than an unnecessary limited power of let
. Is there an elegant way to use bind
inside let
?
As a syntactical convenience, do notation does not add anything essential, but it is often preferable for clarity and style. However, do is not needed for a single action, at all. The Haskell "Hello world" is simply: main = putStrLn "Hello world!"
return is actually just a simple function in Haskell. It does not return something. It wraps a value into a monad.
Am I correct that inside
let
I am forced to resort to(>>=)
?
No:
main :: IO ()
main = do
let x = do
a <- Just 3
b <- Just 5
return (a, b)
print x
Haskell's layout rule dictates that the body of the binding e
in p = e
mus be intended at least as much as the beginning of p
(or the first binding, if you're using multiple at once). Since let
in do
follows (almost) the same rules as let … in
, you can verify this with the following function:
f :: Int
f =
let x =
3 + 5
in x
This doesn't work, since 3 + 5
doesn't have the same or greater indentation level as x
. However,
f :: Int
f =
let x =
3 + 5
in x
works. Also, while the main
above works, it doesn't really convey that a
and b
are things in x
's do
block, so it's a little bit better to indent them slightly more:
main :: IO ()
main = do
let x = do
a <- Just 3
b <- Just 5
return (a, b)
print x
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With