Haskell – Wejście/Wyjście

Transkrypt

Haskell – Wejście/Wyjście
Haskell – Wejście/Wyjście
W Haskelu funkcje nie mogą zmieniać stanów (w tym
np. zmieniać wartości zmiennej). Funkcja wywołana z
pewnymi ustalonymi argumentami musi zwracać
zawsze tą samą wartość niezależnie od tego ile razy i
w jakim kontekście zostanie wywołana.
Gdyby funkcje wejścia/wyjścia zwracały wartość np.
odczytaną z klawiatury to zaprzeczały by idei Haskella,
gdyż dla dwóch różnych wywołań z tymi samymi
wartościami parametrów otrzymywalibyśmy różne
wyniki.
Haskell – Wejście/Wyjście
Haskell rodzi sobie z tym problemem definiując
typ wejściowo - wyjściowy, którego wartości
zwracają funkcję wejścia – wyjścia np. funkcja
getLine odczytuje linię ze standardowego
wejścia:
ghci> :t getLine
getLine :: IO String
Haskell – Wejście/Wyjście
Ze względu na fakt zmiany stanu jako efekt
uboczny działania funkcji w Hasklellu funkcje
dzielimy na czyste i nieczyste:
Funkcja czysta
Funkcja nieczysta
Przy tych samych argumentach zwraca
ten sam wynik
Przy tych samych argumentach może
zwracać różny wynik
Nie zmienia stanów
Może zmieniać stany
Nie posiada efektów ubocznych
Może posiadać efekty uboczne
Haskell – Wejście/Wyjście
Wartosci zwracane przez funkcje nieczyste (w tym
funkcje wejscia – wyjscia odczytujemy przez wiązanie
wartości:
name <­ getLine
Należy przez to rozumie: wykonaj akcję wejścia wyjścia
getLine i zwiąż jej wynik z name. Przypisanie:
name = getLine
spowodowałoby nadanie funkcji getLine nowej nazwy!
Wiązanie jest odpowiednikiem let dla funkcji czystych.
Haskell – Wejście/Wyjście
Funkcje wejścia – wyjścia:
putChar:: Char­> IO ()
putStr::String­> IO ()
putStrLn::String­> IO ()
print: Show a =>a­> IO ()
getChar:: IO Char
getLine:: IO String
Funkcje wyprowadzające dane zwracają wynik IO (), gdzie () oznacza
typ pusty, zaś funkcje wprowadzające dane zwracają wynik IO a, gdzie
a jest typem wczytywanej wartości.
Haskell – Wejście/Wyjście
Program w Haskellu:
main = putStrLn "Hello, world"
Zapisany w pliku hello.hs kompilujemy:
ghc hello.hs ­o hello
lub
ghc ­­make hello
I wykonujemy:
./hello
Haskell – Wejście/Wyjście
Plik name.hs:
main = do putStrLn"Podaj imie:"
imie<­getLine
putStrLn(„Witaj" ++imie++".")
Uruchamiamy:
runhasklell name.hs
Haskell – Wejście/Wyjście
Taki kod przypomina nieco programowanie
imperatywne. Użycie do pozwala na związanie
wielu kroków wejścia – wyjścia w jedną operację.
Użycie do tworzy akcję wejścia – wyjścia, której
typ jest taki sam jak typ ostatniej operacji. W
związku z tym funkcja main ma sygnaturę
main :: IO <sth> gdzie <sth> jest konkretnym typem.
Haskell – Wejście/Wyjście
Zapis:
imię = "Moje imię to:" ++ getLine
jest niepoprawny.
Haskell – Wejście/Wyjście
Operator >>= przekazuje wynik jednej operacji
wejścia – wyjścia innej np.:
getChar >>= putChar
Jeśli wynik pierwszej operacji nie jest interesujący
można użyć operatora >>.
Operator return pozwala zwrócić wartość typu
IO <sth>.
Haskell – Wejście/Wyjście
readln :: IO String readln = do c <­ getChar
if c == '\n' then
return []
else do cs ← readln return ( c:cs )
Haskell – Wejście/Wyjście
getContetnts – zwraca zawartość standardowego
wejścia.
Możliwe jest użycie uchwytów do plików przy pomocy
funkcji:
hgetContents, hPutStr, hPutStrLn, hGetChar, hgetLine
oraz:
openFile, readFile, writeFile, appendFile, withFile.

Podobne dokumenty