Questions tagged [do-notation]

In Haskell, do-notation is syntactic sugar for writing monadic code, expressing computations as sequences of monadic actions. Every participant monadic value in the do block must belong to the same monad.

In Haskell, do-notation is syntactic sugar for writing monadic code expressing computations as sequences of monadic actions, each action possibly calculated -- purely -- from the preceding action's computed results.

Every participant monadic value in the same do block must belong to the same monad.

do-notation explained, in vivid colors.

do blocks translate into monadic code, but we can view this fact as implementational detail, at first. We can treat the do notation axiomatically, as an embedded language.

do blocks express sequences of monadic "actions". A simplified, standardized do-syntax is:

   do {  pattern1 <- action1
      ;  pattern2 <- action2
      ;  pattern3 <- action3
      .....................
      ;  return result
      }

Each actioni is a Haskell expression of type M ai for some monad M and some result type ai, with M the same for all is. (Examples are: Maybe a, Maybe b, Maybe c; [a], [b], [c]; IO a, IO b, IO c; etc.)

Thus each actioni "produces" its own result type ai "in" the same monad M as all the other actions in the do block.

The overall type of a do block expression is M an where an is the type of the argument result in the final return result action (which thus has the type M an). Put differently, the type of the final action in the do block is the type of the overall do block.

In particular (and a frequent cause of confusion while learning), if actioni is an if expression, each of its branches must be an expression of the same M ai type, an expression that itself could be a do block, if it needs to sequence several M actions.

Each patterni becomes match-bound to the "computed" result from the corresponding actioni, when the whole combined "computation" described by the whole do block actually "runs" (whatever that means specifically, for the specific M type). If the pattern is refutable, and the pattern match fails, the do computation chain is aborted through the invocation of M's fail method; otherwise, the computation chain continues to the next do line.

Each patterni's variable is in scope from the point of its introduction and to the end of the do block. In particular this means that the result expression in the final return result action may refer to any of the patterni's variables, as may any actionj where j > i.

It also means that the binding construct <- is non-recursive: the scope to its right (and above) contains the scope to its left (and below). That in turn means that if any variable is bound more than once, the deeper (nested) binding shadows the outer binding -- any use of a variable's name refers to its most recent binding only.

Wildcards _ can be used to ignore the computed value. If this is the case, the _ <- part can be omitted altogether.

Another special case is that by Monad laws, do { .... ; x <- action ; return x } is equivalent to do { .... ; action }.

The translation of a do code into actual monadic code goes by the rule

   do { pat <- act ; ... }
===
   act >>= f  where
           f pat = do { ... }
           f _   = fail "error-message"

and

   do { act }
===
   act

Optionally, let can also appear in a do block, which has a simple syntax re-write:

   do { actions... 
      ; let {...}          -- no "in", NB!
      ; more_actions...
      }
===
   do { actions...
      ; let {...} 
        in
          do { more_actions... }
      }
159 questions
2
votes
2 answers

Haskell: Function using do notation and returning i.e. Integer value

I want to write a function that read some data using getLine and return i.e. a tuple (Integer, Integer) but using do-notation. Something like this (of course it doesn't work): fun :: (Integer, Integer) fun = do a <- read (getLine::Integer) b…
Danu
  • 77
  • 2
  • 10
2
votes
2 answers

Bind vs Assignment in Haskell

I'm working through the Write Yourself a Scheme tutorial, and one code block made me wonder about the difference between bind and assignment: parseAtom = do first <- letter <|> symbol rest <- many (letter <|> digit <|> symbol) …
1
vote
0 answers

Which JavaScript lib has feature similar to Haskell's do-notation or Scala's for-comprehension?

I am exploring a few JavaScript libraries for functional programming such as Ramda, Sanctuary, etc.,. I've also checked their pipe and compose functions for chaining and composition. But they can't do something like below which use both x and y to…
Pyi Soe
  • 11
  • 1
1
vote
0 answers

The do-notation in Haskell, the >> and the >>= operator and their impact on the final Monad

I am trying to understand Monads and have read and played around with concept from LYAH especially the 'walk the line section': http://learnyouahaskell.com/a-fistful-of-monads#walk-the-line in order to understand how the >>-operator and discarding…
1
vote
1 answer

Haskell's do syntax and its pattern matching behaviour

I am currently trying to understand the do notation as taught in: http://learnyouahaskell.com/for-a-few-monads-more ...Here it is applied to simple functions and not a monad. type Stack = [Int] push :: Int -> Stack -> ((), Stack) push a stack =…
Piskator
  • 605
  • 1
  • 9
1
vote
1 answer

Haskell do notation vs (>>) operator, happstack routing with 'method'

I am learning Haskell, and I'm trying to learn the happstack server as well. I am following the guide at http://happstack.com/docs/crashcourse/index.html#matching-on-request-method-get-post-etc , and their usage of the 'dir' and 'method' functions…
Mattマット
  • 81
  • 1
  • 4
1
vote
1 answer

Little monoid from scratch example in Haskell with a bug while chaining the monoid

I think I have understood monoids *partly*. But I still have an issue. I don't know what Haskell wants from me in this case here. Why am I not able to chain my monad? Code: data Result a = Result a | Err String | Empty instance Semigroup (Result a)…
peni4142
  • 426
  • 1
  • 7
  • 26
1
vote
2 answers

In what does this simple do notation desugar to?

I'm using Aeson and Network.HTTP. I was able to encode a json and print it on the screen doing the following: getCode :: String -> IO ResponseCode getCode url = simpleHTTP req >>= getResponseCode where req = getRequest url main :: IO () main =…
Guerlando OCs
  • 1,886
  • 9
  • 61
  • 150
1
vote
2 answers

Different let in for lines in do block

I want to create some tests with varying values, using hspec. I wrote the following code which does not compile but give an idea of what I am aiming at: spec :: Spec spec = do describe "productOneLine" $ do let inVector =…
vkubicki
  • 1,104
  • 1
  • 11
  • 26
1
vote
1 answer

Type mismatches in Haskell `do` with multiple return values

I have the following code, but on compile I am getting several errors. Can I return two variables as a tuple from a do statement? Couldn't match type ‘[]’ with ‘(,) String’ Expected type: (String, Char) Actual type: String • In a…
pmichaels
  • 139
  • 6
1
vote
3 answers

Conditional change of State in Haskell

I don't know how I can make a conditional change to State Monad in Haskell. Suppose, I have a stack on State Monad. import Control.Monad.State push :: Int -> State [Int] () push x = state $ \xs -> ((), x : xs) pop :: State [Int] Int pop = state $…
Heir
  • 13
  • 2
1
vote
1 answer

Menu variable not in scope Haskell

I am trying to create a menu which read the data from a textfile. But I get three errors that variable not in scope despite having at the start of the IO(). Am I not reading the txt.file properly and is the way I creating the menu…
Rick Po
  • 59
  • 6
1
vote
2 answers

Converting expression with >>= to do notation

I have the following code newtype State s a = State { runState :: s -> (s,a) } evalState :: State s a -> s -> a evalState sa s = snd $ runState sa s instance Functor (State s) where fmap f sa = State $ \s -> let (s',a) = runState sa s…
Tomer
  • 1,159
  • 7
  • 15
1
vote
0 answers

Cascading the bind (`>>=`) operator

I have the following function bar :: (Monad m, Num b) => m b -> m b -> m b -> m b bar x y z = do x' <- x y' <- y z' <- z return $ x' + y' + z' and I'm trying to write it without the 'do'…
Tomer
  • 1,159
  • 7
  • 15
1
vote
2 answers

How does the do notation in Monad mean in Haskell

Consider the following code segment import Control.Monad.State type Stack = [Int] pop :: State Stack Int pop = state $ \(x:xs) -> (x, xs) push :: Int -> State Stack () push a = state $ \xs -> ((), a:xs) stackManip :: State Stack Int stackManip…