Skip to main content

Home/ Haskell/ Group items tagged io

Rss Feed Group items tagged

Javier Neira

A Neighborhood of Infinity: The IO Monad for People who Simply Don't Care - 0 views

  • Many programming languages make a distinction between expressions and commands.
  • Like other languages it makes the distinction, and like other languages it has its own slightly idiosyncratic notion of what the difference is. The IO monad is just a device to help make this distinction.
  • There is no room for anything like a print command here because a print command doesn't return a value, it produces output as a side-effect
  • ...18 more annotations...
  • It's easy to use: you just write do and then follow it by an indented list of commands. Here's a complete Haskell program:
  • Note also that commands take arguments that can be expressions. So print (2*x) is a command, but 2*x is an expression. Again, little different from a language like Python.
  • So here's an interesting feature of Haskell: commands can return values. But a command that returns a value is different from an expression with a value.
  • We have to use <- instead of let ... = ... to get a returned value out of a command. It's a pretty simple rule, the only hassle is you have to remember what's a command and what's a function.
  • get2Lines = do line1 <- getLine line2 <- getLine return (line1,line2)
  • To introduce a list of commands, use do.To return a value from a command, use return.To assign a name to an expression inside a do block use let.To assign a name to the result of a command, use <-.
  • what's a command and what's an expression? If it has any chance of doing I/O it must be a command, otherwise it's probably an expression.
  • Everything in Haskell has a type, even commands. In general, if a command returns a value of type a then the command itself is of type IO a.
  • eturn is simply a function of type a -> IO a that converts a value of type a to a command of type IO a.
  • 5. The type of a sequence of commands is the type of the last line.
  • The type of an if statement is the type of its branches. So if you want an if statement inside a do block, it needs to be a command, and so its branches need to be commands also. So it's
  • If something is of type IO a then it's a command returning an value of type a. Otherwise it's an expression. That's the rule.
  • following the rules above it's completely impossible to put an executed command inside an expression.
  • As the only way to do I/O is with commands, that means you have no way to find out what Haskell is doing inside expressions.
  • If the type isn't IO a, then you can sleep at night in the confidence that there are no side effects.
  • One last thing. Much of what I've said above is false. But what I hope I have done is describe a subset of Haskell in which you can start some I/O programming without having a clue what a monad is.
  • The idea of capturing imperative computations in a type of (immutable) values is lovely. And so is the general pattern we call "monad".
  • main = do return 1 print "Hello"
Javier Neira

Fatvat: Web Sockets and Haskell - 0 views

  •  
    import Network import System.IO import Control.Concurrent import Char serverHandshake = "HTTP/1.1 101 Web Socket Protocol Handshake\r\n\ \Upgrade: WebSocket\r\n\ \Connection: Upgrade\r\n\ \WebSocket-Origin: http://localhost\r\n\ \WebSocket-Location: ws://localhost:9876/\r\n\ \WebSocket-Protocol: sample\r\n\r\n\0" acceptLoop socket = forever $ do (h,_,_) IO () listenLoop h = do sendFrame h "hello from haskell" threadDelay (3 * 1000000) sendFrame h "it works!" return () sendFrame :: Handle -> String -> IO () sendFrame h s = do hPutChar h (chr 0) hPutStr h s hPutChar h (chr 255)
Javier Neira

Monads as containers - HaskellWiki - 0 views

  • A monad is a container type together with a few methods defined on it.
  • all the elements which a monadic container holds at any one time must be the same type (it is homogeneous).
  • map (fmap), return and join,
  • ...15 more annotations...
  • map, (but called fmap in Haskell 98) actually comes from the definition of a functor
  • That is, if f is a functor, and we are given a function of type (a -> b), and a container of type (f a), we can get a new container of type (f b). This is expressed in the type of fmap: fmap :: (Functor f) => (a -> b) -> f a -> f b If you will give me a blueberry for each apple I give you (a -> b), and I have a box of apples (f a), then I can get a box of blueberries (f b). Every monad is a functor.
  • The second method, return, is specific to monads. If m is a monad, then return takes an element of type a, and gives a container of type (m a) with that element in it. So, its type in Haskell is return :: (Monad m) => a -> m a If I have an apple (a) then I can put it in a box (m a).
  • takes a container of containers m (m a), and combines them into one m a in some sensible fashion. Its Haskell type is join :: (Monad m) => m (m a) -> m a
  • If I have a box of boxes of apples (m (m a)) then I can take the apples from each, and put them in a new box (m a).
  • bind or extend, which is commonly given the symbol (>>=)
  • The function that does this for any monad in Haskell is called liftM -- it can be written in terms of return and bind as follows:
  • liftM :: (Monad m) => (a -> b) -> m a -> m b liftM f xs = xs >>= (return . f) -- take a container full of a's, to each, apply f, -- put the resulting value of type b in a new container, -- and then join all the containers together.
  • Well, in Haskell, IO is a monad.
  • Lists are most likely the simplest, most illustrative example
  • The reason that bind is so important is that it serves to chain computations on monadic containers together.
  • You might notice a similarity here between bind and function application or composition, and this is no coincidence.
  • What bind does is to take a container of type (m a) and a function of type (a -> m b). It first maps the function over the container, (which would give an m (m b)) and then applies join to the result to get a container of type (m b). Its type and definition in Haskell is the
  • xs >>= f = join (fmap f xs)
  • bind (>>=)
1 - 6 of 6
Showing 20 items per page