IO Monad (3C) Young Won Lim 1/6/18

Similar documents
IO Monad (3D) Young Won Lim 1/18/18

IO Monad (3C) Young Won Lim 8/23/17

Monad Background (3A) Young Won Lim 11/18/17

Monad Background (3A) Young Won Lim 11/8/17

Monad Background (3A) Young Won Lim 10/5/17

Using Monads for Input and Output

Side Effects (3B) Young Won Lim 11/20/17

Monad Overview (3B) Young Won Lim 1/16/18

Side Effects (3B) Young Won Lim 11/23/17

Side Effects (3B) Young Won Lim 11/27/17

I/O in Haskell. To output a character: putchar :: Char -> IO () e.g., putchar c. To output a string: putstr :: String -> IO () e.g.

Monad Background (3A) Young Won Lim 11/20/17

Side Effects (3A) Young Won Lim 1/13/18

Introduction to Programming: Lecture 19

Monad P1 : Several Monad Types (4A) Young Won Lim 2/13/19

Monad (1A) Young Won Lim 6/9/17

Maybe Monad (3B) Young Won Lim 1/3/18

Maybe Monad (3B) Young Won Lim 12/21/17

Background Operators (1E) Young Won Lim 7/7/18

Monad (3A) Young Won Lim 8/9/17

I/O in Purely Functional Languages. Stream-Based I/O. Continuation-Based I/O. Monads

Applicatives Comparisons (2C) Young Won Lim 3/6/18

State Monad (3D) Young Won Lim 8/31/17

Background Type Classes (1B) Young Won Lim 6/28/18

Programming in Haskell Aug Nov 2015

PROGRAMMING IN HASKELL. Chapter 10 - Interactive Programming

CSCE 314 Programming Languages. Interactive Programming: I/O

CS The IO Monad. Slides from John Mitchell, K Fisher, and S. Peyton Jones

Introduction to Haskell

Monad (1A) Young Won Lim 6/26/17

Monad (1A) Young Won Lim 6/21/17

State Monad Example (3H) Young Won Lim 2/16/18

State Monad Examples (6C) Young Won Lim 9/22/18

References. Monadic I/O in Haskell. Digression, continued. Digression: Creating stand-alone Haskell Programs

HASKELL I/O. Curt Clifton Rose-Hulman Institute of Technology. Please SVN Update your HaskellInClass folder, then open eieio.hs

State Monad Examples (6C) Young Won Lim 9/26/18

Haskell Overview II (2A) Young Won Lim 8/9/16

Background Type Classes (1B) Young Won Lim 6/14/18

GHCi: Getting started (1A) Young Won Lim 6/3/17

State Monad (3D) Young Won Lim 9/25/17

More on functional programming

Haskell Monads CSC 131. Kim Bruce

Polymorphism Overview (1A) Young Won Lim 2/20/18

GHCi: Getting started (1A) Young Won Lim 5/31/17

Monads. Functional Programming (CS4011) Monads

Haskell Overview II (2A) Young Won Lim 9/26/16

EECS 700 Functional Programming

Programming Languages

Haskell: From Basic to Advanced. Part 2 Type Classes, Laziness, IO, Modules

Background Constructors (1A) Young Won Lim 7/9/18

Background Constructors (1A) Young Won Lim 7/5/18

Background Constructors (1A) Young Won Lim 1/22/18

M-Structures (Continued)

Haskell Overview II (2A) Young Won Lim 8/23/16

CS 457/557: Functional Languages

Standard prelude. Appendix A. A.1 Classes

Programming Paradigms Functional languages

Background Constructors (1A) Young Won Lim 6/30/18

GHCi: Getting started (1A) Young Won Lim 5/26/17

INTERACTION FUNCTIONS

Haskell Revision and Exercises

Haskell: From Basic to Advanced. Part 3 A Deeper Look into Laziness

Introduction to Programming in C Department of Computer Science and Engineering. Lecture No. #29 Arrays in C

Principles of Programming Languages

Advanced Programming Handout 7. Monads and Friends (SOE Chapter 18)

Informatics 1 Functional Programming Lectures 15 and 16. IO and Monads. Don Sannella University of Edinburgh

JVM ByteCode Interpreter

CS 440: Programming Languages and Translators, Spring 2019 Mon 2/4

Functional Programming

Monad class. Example: Lambda laughter. The functional IO problem. EDAN40: Functional Programming Functors and Monads

Locks and Threads and Monads OOo My. Stephan Bergmann StarOffice/OpenOffice.org Sun Microsystems

To figure this out we need a more precise understanding of how ML works

Monads. COS 441 Slides 16

Functional Logic Programming Language Curry

A Sudoku Solver (1A) Richard Bird Implementation. Young Won Lim 11/15/16

Principles of Programming Languages (H)

Embedded Domain Specific Languages in Idris Lecture 3: State, Side Effects and Resources

Informatics 1 Functional Programming 19 Tuesday 23 November IO and Monads. Philip Wadler University of Edinburgh

INTRODUCTION TO FUNCTIONAL PROGRAMMING

Day14 A. Young W. Lim Thr. Young W. Lim Day14 A Thr 1 / 14

Haskell Overview III (3A) Young Won Lim 10/4/16

Typed Racket: Racket with Static Types

Haskell Introduction Lists Other Structures Data Structures. Haskell Introduction. Mark Snyder

CSCI Wednesdays: 1:25-2:15 Keller Thursdays: 4:00-4:50 Akerman 211

CS 11 Haskell track: lecture 1

f() ! " Run a higher-priority task? ! " Yield the processor to another task because our ! " Use the processor for some other activity while

CS 410/510: Advanced Programming

CS152: Programming Languages. Lecture 11 STLC Extensions and Related Topics. Dan Grossman Spring 2011

Software System Design and Implementation

About the Tutorial. Audience. Prerequisites. Copyright & Disclaimer. Haskell Programming

Functional Programming and Haskell

CS 457/557: Functional Languages

Advanced Systems Programming

Background Expressions (1D) Young Won Lim 7/7/18

GIS 4653/5653: Spatial Programming and GIS. More Python: Statements, Types, Functions, Modules, Classes

Day14 A. Young W. Lim Tue. Young W. Lim Day14 A Tue 1 / 15

Practical Haskell. An introduction to functional programming. July 21, Practical Haskell. Juan Pedro Villa-Isaza. Introduction.

QUIZ. What is wrong with this code that uses default arguments?

The Haskell HOP: Higher-order Programming

Libraries (1A) Young Won Lim 6/5/17

Transcription:

Copyright (c) 2016-2018 Young W. Lim. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the section entitled "GNU Free Documentation License". Please send corrections (or suggestions) to youngwlim@hotmail.com. This document was produced by using LibreOffice/OpenOffice.

Based on Haskell in 5 steps https://wiki.haskell.org/haskell_in_5_steps 3

>> of IO Monad (>>) :: IO a -> IO b -> IO b (x >> y) if x and y are IO actions then it is the action that first performs x dropping the result then performs y returns its result. https://wiki.haskell.org/introduction_to_io 4

>>= of IO Monad (>>=) :: IO a -> (a -> IO b) -> IO b (x >>= f) to use the result of the first action (x) in order to affect what the second action will do the action that first performs the action x and captures its result passing it to f then f computes a second action to be performed. this second action is then carried out, its result is the result of the overall computation. x >> y = x >>= const y https://wiki.haskell.org/introduction_to_io 5

IO Monad Haskell separates pure functions from computations where side effects must be considered by encoding those side effects as values of a particular type. Specifically, a value of type (IO a) is an action, which if executed would produce a value of type a. https://wiki.haskell.org/introduction_to_io 6

Pure Function A function returns exactly the same result every time it's called with the same set of arguments. A function has no state A function can access no external state A function has no side effects Calling a function once is the same as calling it twice and discarding the result of the first call. laziness easily parallelized no data races https://www.schoolofhaskell.com/school/starting-with-haskell/basics-of-haskell/3-pure-functions-laziness-io 7

Actions Haskell runtime evaluates main (an expression). main evaluates not to a simple value but to an action. The runtime then executes this action. the program itself has no side effects but the action does have side effects IO action is invoked after the Haskell program has run the functional nature of the program https://www.schoolofhaskell.com/school/starting-with-haskell/basics-of-haskell/3-pure-functions-laziness-io 8

Simple IO main calls functions like putstrln or print, which return IO actions. there is only one non-trivial source of IO actions: primitives built into the language. trivially convert any value into an IO action using return. can never execute an IO action inside the program Once created, an IO action keeps percolating up until it ends up in main and is executed by the runtime. can also discard an IO action, but that means it will never be evaluated https://www.schoolofhaskell.com/school/starting-with-haskell/basics-of-haskell/3-pure-functions-laziness-io 9

Laziness Haskell will not calculate anything unless it's strictly necessary or is forced by the programmer won't even evaluate arguments to a function before calling it. assumes that the arguments will not be used by the function procrastinates as long as possible. https://www.schoolofhaskell.com/school/starting-with-haskell/basics-of-haskell/3-pure-functions-laziness-io 10

Laziness Example 1 Division by zero : undefined - never be evaluated. main = print $ undefined + 1 the compiler doesn't complain a runtime error resulting from an attempt to evaluate undefined. foo x = 1 main = print $ (foo undefined) + 1 Haskell calls foo but never evaluates its argument undefined https://www.schoolofhaskell.com/school/starting-with-haskell/basics-of-haskell/3-pure-functions-laziness-io 11

Laziness Example 2 not result from optimization: The compiler sees the definition of foo and figures out that foo and discards its argument. But the result is the same if the definition of foo is hidden from view in another module. {-# START_FILE Foo.hs #-} -- show module Foo (foo) where foo x = 1 {-# START_FILE Main.hs #-} -- show import Foo main = print $ (foo undefined) + 1 https://www.schoolofhaskell.com/school/starting-with-haskell/basics-of-haskell/3-pure-functions-laziness-io 12

Laziness with infinity laziness allows it to deal with infinity (like an infinite list) deal with the future that hasn't materialized yet Laziness or not, a program needs to be executed at some point. there are several reasons why an expression would have to be evaluated -- the fundamental one being that somebody wants to display its result. without I/O nothing would ever be evaluated in Haskell. https://www.schoolofhaskell.com/school/starting-with-haskell/basics-of-haskell/3-pure-functions-laziness-io 13

Do Notation Larger IO actions are built from smaller IO actions. the order of composition must sequence IO actions. special syntax for sequencing : the do notation. sequencing two IO actions one IO action returned by putstrln another IO action returned by print inside a do block with proper indentation. main = do putstrln "The answer is: " print 43 https://www.schoolofhaskell.com/school/starting-with-haskell/basics-of-haskell/3-pure-functions-laziness-io 14

Do Notation input part 1 whatever you receive from the user or from a file you assign to a variable and use it later. main = do str <- getline putstrln str not really a variable not really an assignment creates an action that, when executed will take the input from the user. then pass this input to the rest of actions of the do block under the name str when the rest is executed. https://www.schoolofhaskell.com/school/starting-with-haskell/basics-of-haskell/3-pure-functions-laziness-io 15

Do Notation input part 2 str <- getline In Haskell you never assign to a variable, instead you bind a name to a value. When the action produced by the do block is executed, it binds the name str to the value returned by executing the action that was produced by getline. https://www.schoolofhaskell.com/school/starting-with-haskell/basics-of-haskell/3-pure-functions-laziness-io 16

Monadic Operation the do block is not a special hack that only works for IO actions. Far from that, do blocks are used for sequencing a more general set of monadic operations. IO is just one example of a monad the idea of a monad is that it has an imperative feel. Monadic do blocks really look like chunks of imperative code. They also behave like imperative code all imperative programming is at its core monadic. The way the actions are glued together is the essence of the Monad. Since the glueing happens between the lines, the Monad is sometimes described as an "overloading of the semicolon." Different monads overload it differently. https://www.schoolofhaskell.com/school/starting-with-haskell/basics-of-haskell/3-pure-functions-laziness-io 17

IO ( ) getline :: IO String putstrln :: String -> IO () -- note that the result value is an empty tuple. randomrio :: (Random a) => (a,a) -> IO a Normally Haskell evaluation doesn't cause this execution to occur. A value of type (IO a) is almost completely inert. the only IO action is to run in main main :: IO () main = putstrln "Hello, World!" main = putstrln "Hello" >> putstrln "World" main = putstrln "Hello, what is your name?" >> getline >>= \name -> putstrln ("Hello, " ++ name ++ "!") https://wiki.haskell.org/introduction_to_io 18

randomrio randomr :: RandomGen g => (a, a) -> g -> (a, g) takes a range (lo,hi) and a random number generator g, and returns a random value uniformly distributed in the closed interval [lo,hi], together with a new generator. randomrio :: (a, a) -> IO a A variant of randomr that uses the global random number generator See System.Random https://hackage.haskell.org/package/random-1.1/docs/system-random.html 19

RandomRIO Example import System.Random main = do putstr. show =<< randomrio (0, 100 :: Int) putstr ", " print =<< randomrio (0, 100 :: Int) print =<< (randomio :: IO Float) $ runhaskell random-numbers.hs 51, 15 0.2895795 https://hackage.haskell.org/package/random-1.1/docs/system-random.html 20

IO ( ) main = putstrln "Hello, what is your name?" >> getline >>= \name -> putstrln ("Hello, " ++ name ++ "!") main = do putstrln "Hello, what is your name?" name <- getline putstrln ("Hello, " ++ name ++ "!") return :: a -> IO a Note that there is no function: unsafe :: IO a -> a https://wiki.haskell.org/introduction_to_io 21

Basic IO getchar :: IO Char putchar :: Char -> IO () main :: IO () main = do c <- getchar putchar c ready ready :: IO Bool = do c <- getchar c == 'y' -- Bad!!! https://www.haskell.org/tutorial/io.html 22

Basic IO return :: a -> IO a getline getline :: IO String = do c <- getchar if c == '\n' then return "" else do l <- getline return (c:l) https://www.haskell.org/tutorial/io.html 23

Basic IO f :: Int -> Int -> Int absolutely cannot do any I/O since IO does not appear in the returned type. Basically, it is not intended to place print statements liberally throughout their code during debugging in Haskell. There are some unsafe functions available to get around this problem but these are not recommended. Debugging packages (like Trace) often make liberal use of these forbidden functions' in an entirely safe manner. https://www.haskell.org/tutorial/io.html 24

Actions todolist :: [IO ()] todolist = [putchar 'a', do putchar 'b' putchar 'c', do c <- getchar putchar c] sequence_ :: [IO ()] -> IO () sequence_ [] = return () sequence_ (a:as) = do a sequence as do x;y x >> y https://www.haskell.org/tutorial/io.html 25

Actions sequence_ :: [IO ()] -> IO () sequence_ = foldr (>>) (return ()) putstr :: String -> IO () putstr s = sequence_ (map putchar s) https://www.haskell.org/tutorial/io.html 26

Exception Handling Errors are encoded using a special data type, IOError. This type represents all possible exceptions that may occur within the I/O monad. This is an abstract type: no constructors for IOError are available to the user. iseoferror :: IOError -> Bool https://www.haskell.org/tutorial/io.html 27

Exception Handling An exception handler has type IOError -> IO a. The catch function associates an exception handler with an action or set of actions The arguments to catch are an action and a handler. catch :: IO a -> (IOError -> IO a) -> IO a If the action succeeds, its result is returned without invoking the handler. If an error occurs, it is passed to the handler as a value of type IOError and the action associated with the handler is then invoked https://www.haskell.org/tutorial/io.html 28

Exception Handling catch :: IO a -> (IOError -> IO a) -> IO a getchar' getchar' :: IO Char = getchar `catch` (\e -> return '\n') getchar' :: IO Char getchar' = getchar `catch` eofhandler where eofhandler e = if iseoferror e then return '\n' else ioerror e iseoferror :: IOError -> Bool ioerror :: IOError -> IO a https://www.haskell.org/tutorial/io.html 29

Exception Handling getline' :: IO String getline' = catch getline'' (\err -> return ("Error: " ++ show err)) where getline'' = do c <- getchar' if c == '\n' then return "" else do l <- getline' return (c:l) https://www.haskell.org/tutorial/io.html 30

Files, Channels, Handles type FilePath = String -- path names in the file system openfile :: FilePath -> IOMode -> IO Handle hclose :: Handle -> IO () data IOMode = ReadMode WriteMode AppendMode ReadWriteMode Opening a file creates a handle (of type Handle) for use in I/O transactions. Closing the handle closes the associated file: https://www.haskell.org/tutorial/io.html 31

Files, Channels, Handles Handles can also be associated with channels: communication ports not directly attached to files. Predefined channel handles :stdin, stdout, and stderr Character level I/O operations include hgetchar and hputchar, which take a handle as an argument. The getchar function used previously can be defined as: getchar = hgetchar stdin Haskell also allows the entire contents of a file or channel to be returned as a single string: getcontents :: Handle -> IO String https://www.haskell.org/tutorial/io.html 32

Files, Channels, Handles main = do fromhandle <- getandopenfile "Copy from: " ReadMode tohandle <- getandopenfile "Copy to: " WriteMode contents <- hgetcontents fromhandle hputstr tohandle contents hclose tohandle putstr "Done." getandopenfile :: String -> IOMode -> IO Handle getandopenfile prompt mode = do putstr prompt name <- getline catch (openfile name mode) (\_ -> do putstrln ("Cannot open "++ name ++ "\n") getandopenfile prompt mode) https://www.haskell.org/tutorial/io.html 33

Functional vs Imperative Programming getline = do c <- getchar if c == '\n' then return "" else do l <- getline return (c:l) function getline() { c := getchar(); if c == `\n` then return "" else {l := getline(); return c:l}} https://www.haskell.org/tutorial/io.html 34

35

IO ( ) put :: s -> State s ( ) put :: s -> (State s) ( ) one value input type s the effect-monad State s the value output type ( ) the operation is used only for its effect; the value delivered is uninteresting putstr :: String -> IO () delivers a string to stdout but does not return anything exciting. https://stackoverflow.com/questions/16892570/what-is-in-haskell-exactly 36

Monadic Effect class Monad m where return :: a -> m a (>>=) :: m a -> (a -> m b) -> m b https://en.wikibooks.org/wiki/haskell/understanding_monads/io https://stackoverflow.com/questions/2488646/why-are-side-effects-modeled-as-monads-in-haskell https://stackoverflow.com/questions/7840126/why-monads-how-does-it-resolve-side-effects https://stackoverflow.com/questions/2488646/why-are-side-effects-modeled-as-monads-in-haskell https://www.cs.hmc.edu/~adavidso/monads.pdf 37

IO ( ) Monadic operations tend to have types which look like val-in-type-1 ->... -> val-in-type-n -> effect-monad val-out-type where the return type is a type application: the function tells you which effects are possible and the argument tells you what sort of value is produced by the operation https://stackoverflow.com/questions/16892570/what-is-in-haskell-exactly 38

Side Effects in Haskell Generally, a monad cannot perform side effects in Haskell. there is one exception: IO monad Suppose there is a type called World, which contains all the state of the external universe A way of thinking what IO monad does World -> (t, World) type IO t = World -> (t, World) type synonym World (t, World) IO t is a function input : a World output: the t it s supposed to contain, a new, updated World obtained by modifying the given World in the process of computing the t. World IO x world0 IO t (t, World) (x, world1) https://www.cs.hmc.edu/~adavidso/monads.pdf 39

Side Effects in Haskell instance Monad IO where return x world = (x, world) (iox >>= f) world0 = let (x, world1) = iox world0 in f x world1 -- Has type (t, World) x World iox (t, World) t World f (t, World) world0 (x, world1) world1 f x world1 https://www.cs.hmc.edu/~adavidso/monads.pdf 40

Side Effects in Haskell The return function takes x and gives back a function that takes a World and returns x along with the new, updated World formed by not modifying the World it was given return x world = (x, world) x return World (x, World). https://www.cs.hmc.edu/~adavidso/monads.pdf 41

Side Effects in Haskell the expression (iox >>= f) has type World -> (t, World) a function that takes a World, called world0, which is used to extract x from its IO monad. This gets passed to f, resulting in another IO monad, which again is a function that takes a World and returns a x and a new, updated World. We give it the World we got back from getting x out of its monad, and the thing it gives back to us is the t with a final version of the World. the implementation of bind x World iox (t, World) t World f (t, World) world0 (x, world1) world1 f x world1 https://www.cs.hmc.edu/~adavidso/monads.pdf 42

References [1] ftp://ftp.geoinfo.tuwien.ac.at/navratil/haskelltutorial.pdf [2] https://www.umiacs.umd.edu/~hal/docs/daume02yaht.pdf