IO (sisend-väljund)
Idrise puhtad funktsioonid ei võimalda teha mittepuhtaid arvutusi. Aga, mittepuhtaid arvutusi saab modelleerida Idrise funktsioonide ja tüüpide abil.
Näiteks tüüp IO a
. Intuitsioon: „masin mis arvutab a
tüüpi väärtuse“
pure : a -> IO a
--- masin tagastab esimese argumendi väärtuse(>>=) : IO a -> (a -> IO b) -> IO b
--- masin käivitab esimese argumendi ja rakendab tulemuse teisele
Lisaks baasfunktsioonid:
putStrLn : String -> IO ()
--- prindib sõne ning uue reaputStr : String -> IO ()
--- prindib sõne ilma uue reatagetLine : IO String
--- loeb rea sisseprintLn : a -> IO ()
--- prindib tüübia
(eeldusel, et tüübila
on impl.Show
liides) ning uue reaprint : a -> IO ()
--- prindib tüübia
(eeldusel, et tüübila
on impl.Show
liides) ilma uue reata
Nii saab kombineerida olemasolevaid IO
„masinaid“. Näiteks:
main : IO () main = randomRIO (1, 10) >>= classify >>= putStrLn where classify : Int -> IO String classify x = if x `mod` 2 == 1 then pure "paaritu" else pure "paaris"
REPL-is saab modelleeritud programmi käima panna nii:
:exec main
do
-süntaks
Eelnevat koodi on keeruline lugeda ja kirjutada. Sama saab saavutada järgnevalt
main : IO () main = do r <- randomRIO (1, 10) c <- classify r putStrLn c where classify : Int -> IO String classify x = ...
või
main : IO () main = do r <- randomRIO (1, 10) if x `mod` 2 == 1 then putStrLn "paaritu" else putStrLn "paaris"
Do-süntaks algab do
-võtmesõnaga, millele järgnevad järjest töödeldavad laused.
- Laused mustriga
x <-p
, kusp : IO a
siis peale seda lausetx : a
let
laused ning,- avaldised
e
, mille tüüp onIO a
.
Pane tähele: do
seob kokku IO-avaldised, kuid ei saa vaadata konstruktsioonide sisse
- ühe avaldise jaoks pole
do
-d vajamain = putStrLn "Hello World!"
- Hargenmise puhul võib olla vaja kasutada mitut
do
-d:
main : IO () main = do putStrLn "Kirjuta midagi!" xs <- getLine if (xs=="") then putStr "Sõnakuulmatu!" else do putStrLn "Tänan!" putStrLn ("Kirjutasid: " ++ xs)
do
tähendus
a >>= f
on sama mis
do x <- a f x
a >> b
on sama mis
do a b
do a do do a do a b on sama mis b on sama mis do b c c c
Fixity:
infixl 1 >> infixl 1 >>=
Näide:
main : IO () main = do putStrLn "Kirjuta midagi!" xs <- getLine if (xs=="") then putStr "Sõnakuulmatu!" else do putStrLn "Tänan!" putStrLn ("Kirjutasid: " ++ xs)
on sama mis
main : IO () main = putStrLn "Kirjuta midagi!" >> getLine >>= (\ xs => if (xs=="") then putStr "Sõnakuulmatu!" else putStrLn "Tänan!" >> putStrLn ("Kirjutasid: " ++ xs) )
on sama mis
main : IO () main = do let ifTE : String -> IO () ifTE xs = if (xs=="") then putStr "Sõnakuulmatu!" else putStrLn "Tänan!" >> putStrLn ("Kirjutasid: "++xs) putStrLn "Kirjuta midagi!" >> getLine >>= ifTE