F12, then click Console
F12, then click Console
-- Designed by Anish S. Tondwalkar import Graphics.Gloss.Data.Point import Graphics.Gloss.Geometry.Line -- A line is specified by two points (a point is a pair of Floats) data Line = L Point Point -- takes two lines instead of two points intersectLines (L a b) (L c d) = intersectLineLine a b c d
Remember, Haskell is pure.
(no modification of global variables)
Let's print out some output!
Create a file
Main.hs and write the following code
module Main where main = do putStrLn "Hello world!" putStrLn "main is a function" putStrLn "of type IO ()"
Run the code
Or just use
Or compile the code!
main is the "entry point of a Haskell program" *
It must be an IO type.
$ ghci Main.hs *Main> :t main main :: IO ()
It's like the
main from Java or C++. When you compile Haskell code, the
main function runs.
glues together multiple IO actions
do is a keyword in Haskell, like
main = do putStrLn "this line is the first IO action" putStrLn "putStrLn has type String -> IO ()" putStrLn "we are glueing together multiple IO ()"
Input is just as straight forward.
getLine function binds input to a variable.
module Main where main = do putStrLn "Why did the banker leave his job?" answer <- getLine putStrLn (if answer == "he lost interest" then "Correct!" else "Wrong!")
We have seen the
<- symbol before
[ x | x<-[1..10], even x ]
The symbol is pronounced "drawn from"
main = do input <- getLine putStrLn ("you wrote: " ++ input)
"input is drawn from getLine"
If you see IO, think side effects.
putStrLn displays something to your monitor. That's a side effect!
putStrLn gives back nothing, ()
Prelude> :t putStrLn putStrLn :: String -> IO ()
getLine gives back a String to use
Prelude> :t getLine getLine :: IO String
Side-effects are isolated into I/O actions.
Pure code is separated from impure operations.
I/O actions only exist within other I/O actions.
return is a function that "makes an I/O action out of a pure value" *
Prelude> :t return return :: Monad m => a -> m a
return "hello" :: IO String
It's pretty much the opposite of the
main = do input <- return "hello" putStrLn input
return packs up a value into an IO box.
<- extracts the value out of an IO box.
In this program, we exit when the input is "y"
module Main where main = do putStrLn "quit the program? y/n" ans <- getLine if ans /= "y" then do putStrLn "not quitting" main else return ()
return () has the type IO ()
We create an IO that doesn't do anything so that the program could exit.
The when function from Control.Monad module looks nicer
when :: Monad m => Bool -> m () -> m ()
sequence evaluates each IO action from a list of actions and returns a list of IO outputs
sequence :: Monad m => [m a] -> m [a]
Prelude> sequence [getLine, getLine] hello world ["hello","world"]
Prelude> sequence (map print [1,2]) 1 2 [(),()]
print is equivalent to putStrLn.show
mapM takes care of the sequencing stuff
Prelude> mapM print [1,2,3] 1 2 3 [(),(),()]
and mapM_ is the same but doesn't output anything afterwards
Prelude> mapM_ print [1,2,3] 1 2 3
interact makes I/O really easy.
interact on a String -> String function and you're done!
module Main where main = interact countChars countChars :: String -> String countChars str = let allLines = lines str lengths = map (show.length) allLines in unlines lengths
module Main where import System.IO main = do theInput <- readFile "input.txt" putStrLn (countLines theInput) countLines :: String -> String countLines str = (show (length (lines str)))
Writing to file is done with writeFile
writeFile will overwrite the file. Use appendFile if you'd like to append instead
module Main where import System.IO main = do putStrLn "writing to file..." writeFile "output.txt" ['A'..'Z']
Write an IO program that reverses textgiven a file containing some text, create an output file with everything in reverse