ΠΡΠΎΡΡΠ΅ΠΉΡΠΈΠΉ ΡΠΏΠΎΡΠΎΠ± Π²ΡΠΏΠΎΠ»Π½ΠΈΡΡ Π΄Π΅ΠΉΡΡΠ²ΠΈΠ΅, ΠΊΠΎΡΠΎΡΠΎΠ΅ ΠΏΠΎΡΠ΅Π½ΡΠΈΠ°Π»ΡΠ½ΠΎ ΠΌΠΎΠΆΠ΅Ρ Π²ΡΠ·Π²Π°ΡΡ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅,β Π²ΠΎΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡΡΡ ΡΡΠ½ΠΊΡΠΈΠ΅ΠΉ try:
try :: Exception e => IO a -> IO (Either e a)
Π€ΡΠ½ΠΊΡΠΈΡ try ΠΏΡΡΠ°Π΅ΡΡΡ Π²ΡΠΏΠΎΠ»Π½ΠΈΡΡ ΠΏΠ΅ΡΠ΅Π΄Π°Π½Π½ΠΎΠ΅ Π΅ΠΉ Π΄Π΅ΠΉΡΡΠ²ΠΈΠ΅ Π²Π²ΠΎΠ΄Π°-Π²ΡΠ²ΠΎΠ΄Π° ΠΈ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅Ρ Π»ΠΈΠ±ΠΎ Right <ΡΠ΅Π·ΡΠ»ΡΡΠ°Ρ Π΄Π΅ΠΉΡΡΠ²ΠΈΡ> Π»ΠΈΠ±ΠΎ Left <ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅>, Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ:
ghci> try (print $ 5 `div` 2) :: IO (Either ArithException ())
2
Right ()
ghci> try (print $ 5 `div` 0) :: IO (Either ArithException ())
Left divide by zero
ΠΠ±ΡΠ°ΡΠΈΡΠ΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, ΡΡΠΎ Π² Π΄Π°Π½Π½ΠΎΠΌ ΡΠ»ΡΡΠ°Π΅ ΠΏΠΎΡΡΠ΅Π±ΠΎΠ²Π°Π»ΠΎΡΡ ΡΠ²Π½ΠΎ ΡΠΊΠ°Π·Π°ΡΡ ΡΠΈΠΏ Π²ΡΡΠ°ΠΆΠ΅Π½ΠΈΡ, ΠΏΠΎΡΠΊΠΎΠ»ΡΠΊΡ Π΄Π»Ρ Π²ΡΠ²ΠΎΠ΄Π° ΡΠΈΠΏΠ° ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΠΈ Π½Π΅Π΄ΠΎΡΡΠ°ΡΠΎΡΠ½ΠΎ. ΠΠΎΠΌΠΈΠΌΠΎ ΠΏΡΠΎΡΠ΅Π³ΠΎ, ΡΠΊΠ°Π·Π°Π½ΠΈΠ΅ ΡΠΈΠΏΠ° ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΡ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ ΠΎΠ±ΡΠ°Π±Π°ΡΡΠ²Π°ΡΡ Π½Π΅ Π²ΡΠ΅ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΡ, Π° ΡΠΎΠ»ΡΠΊΠΎ Π½Π΅ΠΊΠΎΡΠΎΡΡΠ΅. Π ΡΠ»Π΅Π΄ΡΡΡΠ΅ΠΌ ΠΏΡΠΈΠΌΠ΅ΡΠ΅ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ ΡΡΠ½ΠΊΡΠΈΠ΅ΠΉ try ΠΎΠ±Π½Π°ΡΡΠΆΠ΅Π½ΠΎ Π½Π΅ Π±ΡΠ΄Π΅Ρ:
> try (print $ 5 `div` 0) :: IO (Either IOException ())
*** Exception: divide by zero
Π£ΠΊΠ°Π·Π°Π½ΠΈΠ΅ ΡΠΈΠΏΠ° SomeException ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ ΠΎΠ±Π½Π°ΡΡΠΆΠΈΡΡ Π»ΡΠ±ΠΎΠ΅ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅:
ghci> try (print $ 5 `div` 0) :: IO (Either SomeException ())
Left divide by zero
ΠΠΎΠΏΡΠΎΠ±ΡΠ΅ΠΌ Π½Π°ΠΏΠΈΡΠ°ΡΡ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ, ΠΊΠΎΡΠΎΡΠ°Ρ ΠΏΡΠΈΠ½ΠΈΠΌΠ°Π΅Ρ Π΄Π²Π° ΡΠΈΡΠ»Π° Π² Π²ΠΈΠ΄Π΅ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠΎΠ² ΠΊΠΎΠΌΠ°Π½Π΄Π½ΠΎΠΉ ΡΡΡΠΎΠΊΠΈ, Π΄Π΅Π»ΠΈΡ ΠΏΠ΅ΡΠ²ΠΎΠ΅ ΡΠΈΡΠ»ΠΎ Π½Π° Π²ΡΠΎΡΠΎΠ΅ ΠΈ Π½Π°ΠΎΠ±ΠΎΡΠΎΡ ΠΈ Π²ΡΠ²ΠΎΠ΄ΠΈΡ ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΡ. ΠΠ°ΡΠ΅ΠΉ ΠΏΠ΅ΡΠ²ΠΎΠΉ ΡΠ΅Π»ΡΡ Π±ΡΠ΄Π΅Ρ ΠΊΠΎΡΡΠ΅ΠΊΡΠ½Π°Ρ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠ° ΠΎΡΠΈΠ±ΠΊΠΈ Π΄Π΅Π»Π΅Π½ΠΈΡ Π½Π° Π½ΠΎΠ»Ρ.
import Control.Exception
import System.Environment
printQuotients :: Integer -> Integer -> IO ()
printQuotients a b = do
print $ a `div` b
print $ b `div` a
params :: [String] -> (Integer, Integer)
params [a,b] = (read a, read b)
main = do
args <- getArgs
let (a, b) = params args
res <- try (printQuotients a b) :: IO (Either ArithException ())
case res of
Left e -> putStrLn "ΠΠ΅Π»Π΅Π½ΠΈΠ΅ Π½Π° 0!"
Right () -> putStrLn "OK"
putStrLn "ΠΠΎΠ½Π΅Ρ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ"
ΠΠΎΠ³ΠΎΠ½ΡΠ΅ΠΌ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ Π½Π° ΡΠ°Π·Π»ΠΈΡΠ½ΡΡ Π·Π½Π°ΡΠ΅Π½ΠΈΡΡ :
$ ./quotients 20 7
2
0
OK
ΠΠΎΠ½Π΅Ρ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ
$ ./quotients 0 7
0
ΠΠ΅Π»Π΅Π½ΠΈΠ΅ Π½Π° 0!
ΠΠΎΠ½Π΅Ρ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ
$ ./quotients 7 0
ΠΠ΅Π»Π΅Π½ΠΈΠ΅ Π½Π° 0!
ΠΠΎΠ½Π΅Ρ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ
ΠΠΎΠ½ΡΡΠ½ΠΎ, ΡΡΠΎ ΠΏΠΎΠΊΠ° ΡΡΠ° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ° Π½Π΅ΡΡΡΠΎΠΉΡΠΈΠ²Π° ΠΊ Π΄ΡΡΠ³ΠΈΠΌ Π²ΠΈΠ΄Π°ΠΌ ΠΎΡΠΈΠ±ΠΎΠΊ. Π ΡΠ°ΡΡΠ½ΠΎΡΡΠΈ, ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ Β«Π·Π°Π±ΡΡΡΒ» ΠΏΠ΅ΡΠ΅Π΄Π°ΡΡ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΡ ΠΊΠΎΠΌΠ°Π½Π΄Π½ΠΎΠΉ ΡΡΡΠΎΠΊΠΈ ΠΈΠ»ΠΈ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΡ ΠΈΡ Π½Π΅ Π² ΡΠΎΠΌ ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²Π΅:
$ ./quotients
quotients: quotients.hs:10:1-31: Non-exhaustive patterns in function params
$ ./quotients 2 3 4
quotients: quotients.hs:10:1-31: Non-exhaustive patterns in function params
ΠΡΠΎ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ Π³Π΅Π½Π΅ΡΠΈΡΡΠ΅ΡΡΡ ΠΏΡΠΈ Π²ΡΠ·ΠΎΠ²Π΅ ΡΡΠ½ΠΊΡΠΈΠΈ params, Π΅ΡΠ»ΠΈ ΠΏΠ΅ΡΠ΅Π΄Π°Π½Π½ΡΠΉ Π΅ΠΉ ΡΠΏΠΈΡΠΎΠΊ ΠΎΠΊΠ°Π·ΡΠ²Π°Π΅ΡΡΡ Π½Π΅ Π΄Π²ΡΡ ΡΠ»Π΅ΠΌΠ΅Π½ΡΠ½ΡΠΌ. ΠΠΎΠΆΠ½ΠΎ ΡΠ°ΠΊΠΆΠ΅ ΡΠΊΠ°Π·Π°ΡΡ Π½Π΅ΡΠΈΡΠ»ΠΎΠ²ΡΠ΅ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΡ:
$ ./quotients a b
quotients: Prelude.read: no parse
ΠΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ Π·Π΄Π΅ΡΡ Π³Π΅Π½Π΅ΡΠΈΡΡΠ΅ΡΡΡ ΡΡΠ½ΠΊΡΠΈΠ΅ΠΉ read, ΠΊΠΎΡΠΎΡΠ°Ρ Π½Π΅ Π² ΡΠΎΡΡΠΎΡΠ½ΠΈΠΈ ΠΏΡΠ΅ΠΎΠ±ΡΠ°Π·ΠΎΠ²Π°ΡΡ ΠΏΠ΅ΡΠ΅Π΄Π°Π½Π½ΡΠΉ Π΅ΠΉ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡ ΠΊ ΡΠΈΡΠ»ΠΎΠ²ΠΎΠΌΡ ΡΠΈΠΏΡ.
Π§ΡΠΎΠ±Ρ ΡΠΏΡΠ°Π²ΠΈΡΡΡΡ Ρ Π»ΡΠ±ΡΠΌΠΈ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΡΠΌΠΈ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΡΠΌΠΈ, Π²ΡΠ΄Π΅Π»ΠΈΠΌ ΡΠ΅Π»ΠΎ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ Π² ΠΎΡΠ΄Π΅Π»ΡΠ½ΡΡ ΡΡΠ½ΠΊΡΠΈΡ, ΠΎΡΡΠ°Π²ΠΈΠ² Π² ΡΡΠ½ΠΊΡΠΈΠΈ main ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΈΠ΅ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠΎΠ² ΠΊΠΎΠΌΠ°Π½Π΄Π½ΠΎΠΉ ΡΡΡΠΎΠΊΠΈ ΠΈ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΡ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠΉ:
mainAction :: [String] -> IO ()
mainAction args = do
let (a, b) = params args
printQuotients a b
main = do
args <- getArgs
res <- try (mainAction args) :: IO (Either SomeException ())
case res of
Left e -> putStrLn "ΠΡΠΈΠ±ΠΊΠ°"
Right () -> putStrLn "OK"
putStrLn "ΠΠΎΠ½Π΅Ρ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ"
ΠΡ Π±ΡΠ»ΠΈ Π²ΡΠ½ΡΠΆΠ΄Π΅Π½Ρ Π·Π°ΠΌΠ΅Π½ΠΈΡΡ ΡΠΈΠΏ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΡ Π½Π° SomeException ΠΈ ΡΠ΄Π΅Π»Π°ΡΡ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ ΠΎΠ± ΠΎΡΠΈΠ±ΠΊΠ΅ ΠΌΠ΅Π½Π΅Π΅ ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΠ²Π½ΡΠΌ, ΠΏΠΎΡΠΊΠΎΠ»ΡΠΊΡ ΡΠ΅ΠΏΠ΅ΡΡ Π½Π΅ΠΈΠ·Π²Π΅ΡΡΠ½ΠΎ, ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ ΠΊΠ°ΠΊΠΎΠ³ΠΎ Π²ΠΈΠ΄Π° Π² Π΄Π°Π½Π½ΠΎΠΌ ΡΠ»ΡΡΠ°Π΅ ΠΏΡΠΎΠΈΠ·ΠΎΡΠ»ΠΎ.
$ ./quotients a b
ΠΡΠΈΠ±ΠΊΠ°
ΠΠΎΠ½Π΅Ρ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ
$ ./quotients
ΠΡΠΈΠ±ΠΊΠ°
ΠΠΎΠ½Π΅Ρ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ
ΠΠΎΠ½ΡΡΠ½ΠΎ, ΡΡΠΎ Π² ΠΎΠ±ΡΠ΅ΠΌ ΡΠ»ΡΡΠ°Π΅ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠ° ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΡ Π΄ΠΎΠ»ΠΆΠ½Π° Π·Π°Π²ΠΈΡΠ΅ΡΡ ΠΎΡ Π΅Ρ ΡΠΈΠΏΠ°. ΠΡΠ΅Π΄ΠΏΠΎΠ»ΠΎΠΆΠΈΠΌ, ΡΡΠΎ Ρ Π½Π°Ρ ΠΈΠΌΠ΅Π΅ΡΡΡ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊΠΎΠ² Π΄Π»Ρ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠΉ ΡΠ°Π·Π½ΡΡ ΡΠΈΠΏΠΎΠ²:
handleArith :: ArithException -> IO ()
handleArith _ = putStrLn "ΠΠ΅Π»Π΅Π½ΠΈΠ΅ Π½Π° 0!"
handleArgs :: PatternMatchFail -> IO ()
handleArgs _ = putStrLn "ΠΠ΅Π²Π΅ΡΠ½ΠΎΠ΅ ΡΠΈΡΠ»ΠΎ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠΎΠ² ΠΊΠΎΠΌΠ°Π½Π΄Π½ΠΎΠΉ ΡΡΡΠΎΠΊΠΈ!"
handleOthers :: SomeException -> IO ()
handleOthers e = putStrLn $ "ΠΠ΅ΠΈΠ·Π²Π΅ΡΡΠ½ΠΎΠ΅ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅: " ++ show e
Π ΡΠΎΠΆΠ°Π»Π΅Π½ΠΈΡ, ΡΡΠΎΠ±Ρ ΡΠ²ΠΈΠ΄Π΅ΡΡ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ ΠΎΡ ΡΡΠ½ΠΊΡΠΈΠΈ read, Π½ΡΠΆΠ½ΠΎ Π²ΠΎΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡΡΡ Π½Π°ΠΈΠ±ΠΎΠ»Π΅Π΅ ΠΎΠ±ΡΠΈΠΌ ΡΠΈΠΏΠΎΠΌ SomeException.
ΠΠΌΠ΅ΡΡΠΎ ΡΠΎΠ³ΠΎ ΡΡΠΎΠ±Ρ Π²ΡΡΡΠ½ΡΡ Π²ΡΠ·ΡΠ²Π°ΡΡ ΡΡΠ½ΠΊΡΠΈΡ ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊΠ° ΠΏΡΠΈ Π°Π½Π°Π»ΠΈΠ·Π΅ ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΠ° try, ΠΌΠΎΠΆΠ½ΠΎ ΠΏΡΠΈΠΌΠ΅Π½ΠΈΡΡ ΡΡΠ½ΠΊΡΠΈΡ catch, Π²ΠΎΡ Π΅Ρ ΡΠΈΠΏ:
ghci> :t catch
catch :: Exception e => IO a -> (e -> IO a) -> IO a
ΠΠ ΠΠΠΠ§ΠΠΠΠ. ΠΠΎΠ΄ΡΠ»Ρ Prelude ΡΠΊΡΠΏΠΎΡΡΠΈΡΡΠ΅Ρ ΡΡΠ°ΡΡΡ Π²Π΅ΡΡΠΈΡ ΡΡΠ½ΠΊΡΠΈΠΈ catch, ΠΊΠΎΡΠΎΡΠ°Ρ ΡΠΏΠΎΡΠΎΠ±Π½Π° ΠΎΠ±ΡΠ°Π±Π°ΡΡΠ²Π°ΡΡ ΡΠΎΠ»ΡΠΊΠΎ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΡ Π²Π²ΠΎΠ΄Π°-Π²ΡΠ²ΠΎΠ΄Π°. Π§ΡΠΎΠ±Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Π½ΠΎΠ²ΡΠΉ Π²Π°ΡΠΈΠ°Π½Ρ Π΅Ρ ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ΠΈΡ, Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΡΠΊΡΡΠ²Π°ΡΡΠΈΠΉ ΠΈΠΌΠΏΠΎΡΡ: import Prelude hiding (catch).
Π€ΡΠ½ΠΊΡΠΈΡ catch ΠΏΡΠΈΠ½ΠΈΠΌΠ°Π΅Ρ Π² ΠΊΠ°ΡΠ΅ΡΡΠ²Π΅ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠΎΠ² Π΄Π΅ΠΉΡΡΠ²ΠΈΠ΅ ΠΈ ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΡ: Π΅ΡΠ»ΠΈ ΠΏΡΠΈ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ Π΄Π΅ΠΉΡΡΠ²ΠΈΡ Π³Π΅Π½Π΅ΡΠΈΡΡΠ΅ΡΡΡ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅, ΡΠΎ Π²ΡΠ·ΡΠ²Π°Π΅ΡΡΡ Π΅Π³ΠΎ ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊ. Π’ΠΈΠΏ ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊΠ° ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ΅Ρ, ΠΊΠ°ΠΊΠΈΠ΅ ΠΈΠΌΠ΅Π½Π½ΠΎ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΡ Π±ΡΠ΄ΡΡ ΠΎΠ±ΡΠ°Π±ΠΎΡΠ°Π½Ρ. Π Π°ΡΡΠΌΠΎΡΡΠΈΠΌ ΠΏΡΠΈΠΌΠ΅ΡΡ, Π² ΠΊΠΎΡΠΎΡΡΡ ΡΡΠ½ΠΊΡΠΈΡ mainAction Π²ΡΠ·ΡΠ²Π°Π΅ΡΡΡ Π½Π΅ΠΏΠΎΡΡΠ΅Π΄ΡΡΠ²Π΅Π½Π½ΠΎ Π² GHCi:
ghci> mainAction ["2","0"]
*** Exception: divide by zero
ghci> mainAction ["0","2"] `catch` handleArith
0
ΠΠ΅Π»Π΅Π½ΠΈΠ΅ Π½Π° 0!
ghci> mainAction ["2","0"] `catch` handleArgs
*** Exception: divide by zero
ghci> mainAction ["2","0"] `catch` handleOthers
ΠΠ΅ΠΈΠ·Π²Π΅ΡΡΠ½ΠΎΠ΅ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅: divide by zero
ghci> mainAction ["a", "b"] `catch` handleArgs
*** Exception: Prelude.read: no parse
ghci> mainAction ["a", "b"] `catch` handleOthers
ΠΠ΅ΠΈΠ·Π²Π΅ΡΡΠ½ΠΎΠ΅ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅: Prelude.read: no parse
ΠΡΠ»ΠΈ ΡΡΡΠΎΠΊΠ°, Π²ΡΠ²ΠΎΠ΄ΠΈΠΌΠ°Ρ GHCi, Π½Π°ΡΠΈΠ½Π°Π΅ΡΡΡ Ρ ***, ΡΠΎ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΠ΅Π΅ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ Π½Π΅ Π±ΡΠ»ΠΎ ΠΎΠ±ΡΠ°Π±ΠΎΡΠ°Π½ΠΎ. ΠΠ±ΡΠ°ΡΠΈΡΠ΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ Π½Π° ΠΎΠ±ΡΡΠ½ΡΠΉ Π΄Π»Ρ ΡΡΠ½ΠΊΡΠΈΠΈ catch ΠΈΠ½ΡΠΈΠΊΡΠ½ΡΠΉ ΡΠΏΠΎΡΠΎΠ± Π²ΡΠ·ΠΎΠ²Π°. ΠΠ°ΠΌΠ΅ΡΡΡΠ΅ ΡΠ°ΠΊΠΆΠ΅, ΡΡΠΎ ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊ handleOthers ΡΠΏΠΎΡΠΎΠ±Π΅Π½ ΠΎΠ±ΡΠ°Π±ΠΎΡΠ°ΡΡ Π»ΡΠ±ΠΎΠ΅ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅.
ΠΠ΅ΡΠ½ΡΠΌΡΡ ΠΊ ΠΎΡΠ½ΠΎΠ²Π½ΠΎΠΉ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ΅. ΠΠ°ΠΌ Ρ ΠΎΡΠ΅ΡΡΡ, ΡΡΠΎΠ±Ρ Π²ΠΎΠ·Π½ΠΈΠΊΡΠ΅Π΅ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ Π±ΡΠ»ΠΎ ΠΎΠ±ΡΠ°Π±ΠΎΡΠ°Π½ΠΎ Π½Π°ΠΈΠ±ΠΎΠ»Π΅Π΅ ΠΏΠΎΠ΄Ρ ΠΎΠ΄ΡΡΠΈΠΌ ΠΎΠ±ΡΠ°Π·ΠΎΠΌ: Π΅ΡΠ»ΠΈ ΠΏΡΠΎΠΈΠ·ΠΎΡΠ»ΠΎ Π΄Π΅Π»Π΅Π½ΠΈΠ΅ Π½Π° Π½ΠΎΠ»Ρ, ΡΠΎ ΡΠ»Π΅Π΄ΡΠ΅Ρ Π²ΡΠΏΠΎΠ»Π½ΠΈΡΡ handleArith, ΠΏΡΠΈ Π½Π΅Π²Π΅ΡΠ½ΠΎΠΌ ΡΠΈΡΠ»Π΅ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠΎΠ² ΠΊΠΎΠΌΠ°Π½Π΄Π½ΠΎΠΉ ΡΡΡΠΎΠΊΠΈ β handleArgs, Π² ΠΎΡΡΠ°Π»ΡΠ½ΡΡ ΡΠ»ΡΡΠ°ΡΡ β handleOthers. Π ΡΡΠΎΠΌ Π½Π°ΠΌ ΠΏΠΎΠΌΠΎΠΆΠ΅Ρ ΡΡΠ½ΠΊΡΠΈΡ catches, ΠΏΠΎΡΠΌΠΎΡΡΠΈΠΌ Π½Π° Π΅Ρ ΡΠΈΠΏ:
> :t catches
catches :: IO a -> [Handler a] -> IO a
Π€ΡΠ½ΠΊΡΠΈΡ catches ΠΏΡΠΈΠ½ΠΈΠΌΠ°Π΅Ρ Π² ΠΊΠ°ΡΠ΅ΡΡΠ²Π΅ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠΎΠ² Π΄Π΅ΠΉΡΡΠ²ΠΈΠ΅ ΠΈ ΡΠΏΠΈΡΠΎΠΊ ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊΠΎΠ² (ΡΡΠ½ΠΊΡΠΈΠΉ, ΠΊΠΎΡΠΎΡΡΠ΅ ΡΠΏΠ°ΠΊΠΎΠ²Π°Π½Ρ ΠΊΠΎΠ½ΡΡΡΡΠΊΡΠΎΡΠΎΠΌ Π΄Π°Π½Π½ΡΡ Handler) ΠΈ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅Ρ ΡΠ΅Π·ΡΠ»ΡΡΠ°Ρ Π΄Π΅ΠΉΡΡΠ²ΠΈΡ. ΠΡΠ»ΠΈ Π² ΠΏΡΠΎΡΠ΅ΡΡΠ΅ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ ΠΏΡΠΎΠΈΡΡ ΠΎΠ΄ΠΈΡ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅, ΡΠΎ Π²ΡΠ·ΡΠ²Π°Π΅ΡΡΡ ΠΏΠ΅ΡΠ²ΡΠΉ ΠΈΠ· ΠΏΠΎΠ΄Ρ ΠΎΠ΄ΡΡΠΈΡ ΠΏΠΎ ΡΠΈΠΏΡ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΡ ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊΠΎΠ² (ΠΏΠΎΡΡΠΎΠΌΡ, Π² ΡΠ°ΡΡΠ½ΠΎΡΡΠΈ, ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊ handleOthers Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±ΡΡΡ ΠΏΠΎΡΠ»Π΅Π΄Π½ΠΈΠΌ). ΠΠ΅ΡΠ΅ΠΏΠΈΡΠ΅ΠΌ ΡΡΠ½ΠΊΡΠΈΡ main ΡΠ°ΠΊ, ΡΡΠΎΠ±Ρ ΠΊΠΎΡΡΠ΅ΠΊΡΠ½ΠΎ ΠΎΠ±ΡΠ°Π±Π°ΡΡΠ²Π°Π»ΠΈΡΡ Π²ΡΠ΅ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΡΠ΅ ΠΈΡΠΊΠ»ΡΡΠΈΡΠ΅Π»ΡΠ½ΡΠ΅ ΡΠΈΡΡΠ°ΡΠΈΠΈ:
main = do
args <- getArgs
mainAction args `catches`
[Handler handleArith,
Handler handleArgs,
Handler handleOthers]
putStrLn "ΠΠΎΠ½Π΅Ρ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ"
ΠΠΎΡΠΌΠΎΡΡΠΈΠΌ, ΠΊΠ°ΠΊ ΠΎΠ½Π° ΡΠ΅ΠΏΠ΅ΡΡ ΡΠ°Π±ΠΎΡΠ°Π΅Ρ:
$ ./quotients 20 10
2
0
ΠΠΎΠ½Π΅Ρ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ
$ ./quotients
ΠΠ΅Π²Π΅ΡΠ½ΠΎΠ΅ ΡΠΈΡΠ»ΠΎ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠΎΠ² ΠΊΠΎΠΌΠ°Π½Π΄Π½ΠΎΠΉ ΡΡΡΠΎΠΊΠΈ!
ΠΠΎΠ½Π΅Ρ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ
$ ./quotients 2 0
ΠΠ΅Π»Π΅Π½ΠΈΠ΅ Π½Π° 0!
ΠΠΎΠ½Π΅Ρ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ
$ ./quotients a b
ΠΠ΅ΠΈΠ·Π²Π΅ΡΡΠ½ΠΎΠ΅ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅: Prelude.read: no parse
ΠΠΎΠ½Π΅Ρ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ
Π ΡΡΠΎΠΌ ΡΠ°Π·Π΄Π΅Π»Π΅ ΠΌΡ ΡΠ°Π·ΠΎΠ±ΡΠ°Π»ΠΈΡΡ Ρ ΡΠ°Π±ΠΎΡΠΎΠΉ ΡΡΠ½ΠΊΡΠΈΠΉ try, catch ΠΈ catches, ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡΡΠΈΡ ΠΎΠ±ΡΠ°Π±ΠΎΡΠ°ΡΡ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅, Π² ΡΠΎΠΌ ΡΠΈΡΠ»Π΅ ΠΈ Π²ΠΎΠ·Π½ΠΈΠΊΡΠ΅Π΅ Π² ΡΠΈΡΡΠΎΠΌ ΠΊΠΎΠ΄Π΅. ΠΠ°ΠΌΠ΅ΡΡΡΠ΅ Π΅ΡΡ ΡΠ°Π·, ΡΡΠΎ Π²ΡΡ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠ° Π²ΡΠΏΠΎΠ»Π½ΡΠ»Π°ΡΡ Π² ΡΠ°ΠΌΠΊΠ°Ρ Π΄Π΅ΠΉΡΡΠ²ΠΈΠΉ Π²Π²ΠΎΠ΄Π°-Π²ΡΠ²ΠΎΠ΄Π°. ΠΠΎΡΠΌΠΎΡΡΠΈΠΌ ΡΠ΅ΠΏΠ΅ΡΡ, ΠΊΠ°ΠΊ ΡΠ°Π±ΠΎΡΠ°ΡΡ Ρ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΡΠΌΠΈ, ΠΊΠΎΡΠΎΡΡΠ΅ Π²ΠΎΠ·Π½ΠΈΠΊΠ°ΡΡ ΠΏΡΠΈ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΉ Π²Π²ΠΎΠ΄Π°-Π²ΡΠ²ΠΎΠ΄Π°.
ΠΠ±ΡΠ°Π±ΠΎΡΠΊΠ° ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠΉ Π²Π²ΠΎΠ΄Π°-Π²ΡΠ²ΠΎΠ΄Π°
ΠΡΠΊΠ»ΡΡΠ΅Π½ΠΈΡ Π²Π²ΠΎΠ΄Π°-Π²ΡΠ²ΠΎΠ΄Π° ΠΏΡΠΎΠΈΡΡ ΠΎΠ΄ΡΡ, ΠΊΠΎΠ³Π΄Π° ΡΡΠΎ-ΡΠΎ ΠΏΠΎΡΠ»ΠΎ Π½Π΅ ΡΠ°ΠΊ ΠΏΡΠΈ Π²Π·Π°ΠΈΠΌΠΎΠ΄Π΅ΠΉΡΡΠ²ΠΈΠΈ Ρ Π²Π½Π΅ΡΠ½ΠΈΠΌ ΠΌΠΈΡΠΎΠΌ Π² Π΄Π΅ΠΉΡΡΠ²ΠΈΠΈ Π²Π²ΠΎΠ΄Π°-Π²ΡΠ²ΠΎΠ΄Π°, ΡΠ²Π»ΡΡΡΠ΅ΠΌΡΡ ΡΠ°ΡΡΡΡ ΡΡΠ½ΠΊΡΠΈΠΈ main. ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ, ΠΌΡ ΠΏΡΡΠ°Π΅ΠΌΡΡ ΠΎΡΠΊΡΡΡΡ ΡΠ°ΠΉΠ», ΠΈ ΡΡΡ ΠΎΠΊΠ°Π·ΡΠ²Π°Π΅ΡΡΡ, ΡΡΠΎ ΠΎΠ½ Π±ΡΠ» ΡΠ΄Π°Π»ΡΠ½, ΠΈΠ»ΠΈ Π΅ΡΡ ΡΡΠΎ-Π½ΠΈΠ±ΡΠ΄Ρ Π² ΡΡΠΎΠΌ Π΄ΡΡ Π΅. ΠΠΎΡΠΌΠΎΡΡΠΈΡΠ΅ Π½Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ, ΠΎΡΠΊΡΡΠ²Π°ΡΡΡΡ ΡΠ°ΠΉΠ», ΠΈΠΌΡ ΠΊΠΎΡΠΎΡΠΎΠ³ΠΎ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΡΡΡ Π² ΠΊΠΎΠΌΠ°Π½Π΄Π½ΠΎΠΉ ΡΡΡΠΎΠΊΠ΅, ΠΈ Π³ΠΎΠ²ΠΎΡΡΡΡΡ Π½Π°ΠΌ, ΡΠΊΠΎΠ»ΡΠΊΠΎ ΡΡΡΠΎΠΊ ΡΠΎΠ΄Π΅ΡΠΆΠΈΡΡΡ Π² ΡΠ°ΠΉΠ»Π΅:
import System.Environment
import System.IO
main = do
(fileName:_) <β getArgs
contents <β readFile fileName
putStrLn $ "Π ΡΡΠΎΠΌ ΡΠ°ΠΉΠ»Π΅ " ++ show (length (lines contents)) ++
" ΡΡΡΠΎΠΊ!"
ΠΡΠ΅Π½Ρ ΠΏΡΠΎΡΡΠ°Ρ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ°. ΠΡ Π²ΡΠΏΠΎΠ»Π½ΡΠ΅ΠΌ Π΄Π΅ΠΉΡΡΠ²ΠΈΠ΅ Π²Π²ΠΎΠ΄Π°-Π²ΡΠ²ΠΎΠ΄Π° getArgs ΠΈ ΡΠ²ΡΠ·ΡΠ²Π°Π΅ΠΌ ΠΏΠ΅ΡΠ²ΡΡ ΡΡΡΠΎΠΊΡ Π² Π²ΠΎΠ·Π²ΡΠ°ΡΡΠ½Π½ΠΎΠΌ ΡΠΏΠΈΡΠΊΠ΅ Ρ ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡΠΎΠΌ fileName. ΠΠ°ΡΠ΅ΠΌ ΡΠ²ΡΠ·ΡΠ²Π°Π΅ΠΌ ΠΈΠΌΡ contents Ρ ΡΠΎΠ΄Π΅ΡΠΆΠΈΠΌΡΠΌ ΡΠ°ΠΉΠ»Π°. ΠΡΠΈΠΌΠ΅Π½ΡΠ΅ΠΌ ΡΡΠ½ΠΊΡΠΈΡ lines ΠΊ contents, ΡΡΠΎΠ±Ρ ΠΏΠΎΠ»ΡΡΠΈΡΡ ΡΠΏΠΈΡΠΎΠΊ ΡΡΡΠΎΠΊ, ΡΡΠΈΡΠ°Π΅ΠΌ ΠΈΡ ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ ΠΈ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΠΌ Π΅Π³ΠΎ ΡΡΠ½ΠΊΡΠΈΠΈ show, ΡΡΠΎΠ±Ρ ΠΏΠΎΠ»ΡΡΠΈΡΡ ΡΡΡΠΎΠΊΠΎΠ²ΠΎΠ΅ ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π»Π΅Π½ΠΈΠ΅ ΡΠΈΡΠ»Π°. ΠΡΠΎ ΡΠ°Π±ΠΎΡΠ°Π΅Ρ β Π½ΠΎ ΡΡΠΎ ΠΏΠΎΠ»ΡΡΠΈΡΡΡ, Π΅ΡΠ»ΠΈ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΡ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ΅ ΠΈΠΌΡ Π½Π΅ΡΡΡΠ΅ΡΡΠ²ΡΡΡΠ΅Π³ΠΎ ΡΠ°ΠΉΠ»Π°?