wordCounts :: String -> String
putStr (wordCounts "hello clouds\nhello sky")
hello: 2
sky: 1
clouds: 1
Main
,
containing a function called main
module Main where main :: IO () main = (...)
Main
.
IO ()
IO ()
putStr :: String -> IO () print :: Show a => a -> IO () interact :: (String->String) -> IO ()
interact
wordCounts
main :: IO ()
main = interact wordCounts
wordCounts :: String -> String
wordCounts = (...) -- as before
countWords
(assuming the source file name is countWords.hs
)
ghc --make countWords.hs
example.txt
):
./countWords <example.txt
hello: 2
sky: 1
clouds: 1
g1 x = y + y where y = f x g2 x = f x + f x
y = f x
means that we have
two equal, interchangeable things, like in math!
map f . map g == map (f.g)
map f (xs++ys) == map f xs ++ map f ys
filter p (xs++ys) == filter p xs ++ filter p ys
reverse (xs++ys) == reverse ys ++ reverse xs
reverse . map f == map f . reverse
input() - input()
15
12
3
>>>
input
is not pure.
input()
in Haskell:
getLine
hello
"hello"
writeFile "hello.txt" "Hello world!"
readFile "hello.txt"
"Hello world!"
putStr :: String -> IO () getLine :: IO String writeFile :: FilePath -> String -> IO () readFile :: FilePath -> IO String type FilePath = String
IO
IO
getLine
and readFile
?
s <- readFile "hello.txt"
(s,reverse s)
("Hello world!","!dlrow olleH")
<-
allows us to get the result of
an IO operation. Note the types
readFile "hello.txt" :: IO String
s :: String
s =
readFile "hello.txt"
do
notation allows us to use
the left arrow <-
in the same way
inside function definitions.
showTheDifference :: IO () showTheDifference = do putStrLn "Enter two numbers:" x <- readLn y <- readLn putStr "The difference is: " print (x-y)
readLn :: Read a => IO a print :: Show a => a -> IO () putStr :: String -> IO () putStrLn :: String -> IO ()
showTheDifference
Enter two numbers:
15
12
The difference is: 3
getTheDifference :: IO Integer
getTheDifference = do x <- readLn
y <- readLn
return (x-y)
showTheDifference :: IO ()
showTheDifference = do d <- getTheDifference
putStr "The difference is: "
print d
return
:
return :: a -> IO a
IO
do
do
IO
copyFile :: FilePath -> FilePath -> IO () copyFile from to = do s <- readFile from writeFile to s
sortFile :: FilePath -> FilePath -> IO () sortFile from to = do s <- readFile from writeFile to (sortLines s) sortLines = unlines . sort . lines
sortFile
(e.g. applying it to random file names 100 times)
sortLines
with QuickCheck.
doTwice :: IO a -> IO (a,a) doTwice io = do x <- io y <- io return (x,y) don't :: IO a -> IO () don't io = return ()