Hugs 98 iomonad.c6/17/2023 ![]() The () part of the IO type (called a unit type) indicates that nothing is available to be passed on to any later functions or actions. So, putStrLn is a function, but putStrLn x evaluates to an IO action. It is used as an argument for putStrLn and is incorporated into the IO action that results. The "Write your string: " text is a String (remember, that's just a synonym for ). PutStrLn is a function, but it results in an IO action. We've seen all of this before, but let's review. Whew, that is a lot of information there. Main :: IO () putStrLn :: String -> IO () "Write your string: " :: ( > ) :: Monad m => m a -> m b -> m b fmap :: Functor m => ( a -> b ) -> m a -> m b shout :: -> getLine :: IO String ( >= ) :: Monad m => m a -> ( a -> m b ) -> m b Use fmap to apply a function shout that capitalizes all the letters from the string.Let's combine functions with I/O to create a full program that will: Now that we also know that IO is a monad, we can wrap up the discussion we started there.Ĭombining functions and I/O actions In the Prologue chapter, we anticipated some of the key features of this solution. The IO type constructor provides a way to represent actions as Haskell values, so that we can manipulate them with pure functions. That being so, how do we manage actions like opening a network connection, writing a file, reading input from the outside world, or anything else that goes beyond calculating a value? The main insight is: actions are not functions. There is no way to ignore this issue, as any useful program needs to do I/O, even if it is only to display a result. Since lazy computations are only performed when their values become necessary, unfettered lazy I/O would make the order of execution of the real world effects unpredictable. Furthermore, in most cases I/O can't be done lazily. However, input and output operations, which involve interaction with the world outside the confines of the program, can't be expressed through pure functions. ![]() Being entirely contained within the program, the Haskell compiler can evaluate functions thoroughly in order to optimize the compiled code. Test cases can also be set up easily since we can be sure that nothing other than the arguments will influence a function's result. In particular, pure functions are reliable and predictable they ease debugging and validation. Pure functions and lazy evaluation bring forth a number of advantages. ![]() Lazy evaluation means that, by default, Haskell values are only evaluated when some part of the program requires them – perhaps never, if they are never used – and repeated evaluation of the same value is avoided wherever possible. All Haskell functions are pure, which means that, when given the same arguments, they return the same results. Two defining features of Haskell are pure functions and lazy evaluation. ![]()
0 Comments
Leave a Reply. |