Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Types and do notation

Tags:

haskell

monads

This is several questions rolled into one:

  1. In do notation, does each line have to return the same type? For example, can I write one line in a single do block that returns an IO monad, and another that returns an integer? (My understanding, based on how the de-sugaring with >> and >>= seems to work, is that the answer is no.)

  2. If not, then how does the compiler determine what type the lines must all return? In all the examples I've seen, the author takes it as a foregone conclusion that we're just working with IO monads. But how do you know, for a given do block, what each line must return?

  3. Again assuming the answer to #1 is no: How do you use functions that don't return the right kind of monad inside a do block? For example, consider this websockets code:

    application :: MVar ServerState -> WS.Request -> WS.WebSockets WS.Hybi00 ()
    application state rq = do
      WS.acceptRequest rq
      msg <- WS.receiveData :: WS.WebSockets WS.Hybi00 Text
      return ()
    

    Suppose I want to print the value of msg. How would I go about that in a way that doesn't conflict with the type of the do block?

like image 808
rlkw1024 Avatar asked Dec 12 '22 15:12

rlkw1024


1 Answers

  1. In a do-block, each line can return different types, but they must be in the same monad
    • One line can return an IO String and one can return an IO Integer but they both have to be IO.
  2. The same as the rest of Haskell. Type inference. Just like in the rest of Haskell it doesn't always work, and when it doesn't you must annotate as well.
  3. There are 2 ways of doing this
    • let, remember how in GHCi you must use let to declare local variables, you can do the same in a do block. let someMonad = doSomething
      • Notice, no in
    • Monad Transformers! This to big a topic to explain in a blurb, but basically they're monads that have a special function lift which can "lift" another monad into the transformer. Transformers normally end in a T, eg StateT. Pretty much every monad you use has an equivalent transformer.
like image 194
Daniel Gratzer Avatar answered Dec 29 '22 14:12

Daniel Gratzer