рдЗрди рд╕рднреА рдлрдВрдХреНрд╢рдирд▓рд░реНрд╕ рдФрд░ рдореЛрдирд╛рдбреНрд╕ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХреНрдпреЛрдВ рд╣реИ?

рд╣рд╛рд╕реНрдХреЗрд▓, рдлрдВрдХреНрд╢рдирд▓рд░реНрд╕ рдФрд░ рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдореЛрдиреИрдбреНрд╕ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд▓реЗрдЦреЛрдВ рдореЗрдВ рдмрд╣реБрдд рдмрд╛рд░ рдкрд╛рдП рдЬрд╛рддреЗ рд╣реИрдВред
рддреЛ рдЕрдХреНрд╕рд░ рдРрд╕рд╛ рд╣реЛрддрд╛ рд╣реИ рдХрд┐ рдХрднреА-рдХрднреА "рдХреБрдЫ рдирдП рд╕рд╛рдзреБрдУрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд┐рддрдирд╛ рд╕рдВрднрд╡ рд╣реЛ рдЙрддрдирд╛ рдЯрд┐рдкреНрдкрдгреА" рдФрд░ "рдХреБрдЫ рдЙрдкрдпреЛрдЧреА рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд▓рд┐рдЦреЗрдВ" рдХрдо рд╕реЗ рдХрдо рдкрд╛рдП рдЬрд╛рддреЗ рд╣реИрдВред
рдореЗрд░реА рд░рд╛рдп рдореЗрдВ, рдпрд╣ рдЗрдВрдЧрд┐рдд рдХрд░рддрд╛ рд╣реИ рдХрд┐ рд▓реЛрдЧреЛрдВ рдХреЛ рдХрднреА-рдХрднреА рд╕рдордЭ рдореЗрдВ рдирд╣реАрдВ рдЖрддрд╛ рд╣реИ рдХрд┐ рдЗрди рд╕рднреА рдлрд╝рдВрдХреНрд╢рдирд▓рд░реНрд╕ рдФрд░ рдореЛрдирд╛рдбреНрд╕ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХреНрдпреЛрдВ рд╣реИред

рдпрд╣ рд▓реЗрдЦ рдпрд╣ рджрд┐рдЦрд╛рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рд╣реИ рдХрд┐ рдХрд╛рд░реНрдпрд╛рддреНрдордХ рднрд╛рд╖рд╛рдУрдВ рдФрд░ рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рд╣рд╛рд╕реНрдХреЗрд▓ рдХреА рд╢рдХреНрддрд┐ рднреА рдлрдВрдХреНрд╢рдирд▓рд░реНрд╕ рдФрд░ рдореЛрдирд╛рдбреНрд╕ рдХреА рд╢рдХреНрддрд┐ рд╣реИред


рдиреЗрдЯ рдбреЗрдЯрд╛


рдореИрдВ рдЗрд╕реЗ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд╕рд╛рде рджрд┐рдЦрд╛рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░реВрдВрдЧрд╛ рдЬреЛ рдХрд╛рдлреА рдХреГрддреНрд░рд┐рдо рд╣реИ рдФрд░ рд╢рд╛рдпрдж рдмреЗрдХрд╛рд░ рд╣реИ, рд▓реЗрдХрд┐рди рдПрдХ рд╕рдорд╛рди рдХреЛрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдФрд░ рдкреБрди: рдЙрдкрдпреЛрдЧ рдХреЗ рдорд╣рддреНрд╡ рдкрд░ рдЬреЛрд░ рджрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред

"рдХреНрд▓реАрди" рд╢рдмреНрдж рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдореЗрдВ рдЕрддрд┐рднрд╛рд░рд┐рдд рд╣реИред
рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╡рд╛рдХреНрдпрд╛рдВрд╢ "рд░реВрдмреА рдПрдХ рд╡рд┐рд╢реБрджреНрдз рд░реВрдк рд╕реЗ рд╡рд╕реНрддреБ рднрд╛рд╖рд╛ рд╣реИ" рд╣рдо рд╕рдордЭрддреЗ рд╣реИрдВ рдХрд┐ "рд░реВрдмреА рдПрдХ рднрд╛рд╖рд╛ рд╣реИ рдЬрд╣рд╛рдВ рд╕рдм рдХреБрдЫ рд╡рд╕реНрддреБрдУрдВ рд╣реИред"
рд▓реЗрдХрд┐рди рд╡рд╛рдХреНрдпрд╛рдВрд╢ "рд╣рд╛рд╕реНрдХреЗрд▓ рдПрдХ рд╢реБрджреНрдз рдХрд╛рд░реНрдпрд╛рддреНрдордХ рднрд╛рд╖рд╛ рд╣реИ" рдХреЛ "рд╣рд╛рд╕реНрдХреЗрд▓ рдХреЛ рджреБрд╖реНрдкреНрд░рднрд╛рд╡реЛрдВ рдХреЗ рдмрд┐рдирд╛ рдПрдХ рдХрд╛рд░реНрдпрд╛рддреНрдордХ рднрд╛рд╖рд╛" рдХреЗ рд░реВрдк рдореЗрдВ рд╕рдордЭрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред
рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ, рд╣рдо рдПрдХ рдФрд░ рд╕рдВрджрд░реНрдн рдореЗрдВ "рдХреНрд▓реАрди" рд╢рдмреНрдж рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗред
"рд╕реНрд╡рдЪреНрдЫ рдбреЗрдЯрд╛" рд╡рд╣ рдбреЗрдЯрд╛ рд╣реИ рдЬрд┐рд╕реЗ рдореИрдВ рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВред
рдореВрд▓ рд░реВрдк рд╕реЗ, рдЖрджрд┐рдо рдкреНрд░рдХрд╛рд░ рд╕рдВрдЦреНрдпрд╛, рддрд╛рд░, рдХрднреА-рдХрднреА рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рд╣реЛрддреЗ рд╣реИрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдПрдХ рдЪрд┐рддреНрд░ рдпрд╛ рдХрдИ рдорд╛рдиред
рддрджрдиреБрд╕рд╛рд░, "рдЧрдВрджрд╛ рдбреЗрдЯрд╛" рд╡рд╣ рдбреЗрдЯрд╛ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдореИрдВ рдЬреЛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ, рдЕрддрд┐рд░рд┐рдХреНрдд рдЬрд╛рдирдХрд╛рд░реА рд╢рд╛рдорд┐рд▓ рд╣реИред

рдпрд╣рд╛рдБ рд╣рдо рдЗрд╕ рдХрд╛рд░реНрдпрдХреНрд░рдо рдХреА рд░рдЪрдирд╛ рдХрд░рддреЗ рд╣реИрдВ:
module Main where foo = undefined --   main :: IO () main = do putStrLn "Input a: " a <- getLine --  1    putStrLn "Input b: " b <- getLine --  2    print (foo ab) --    

рдпрд╣ рдХрд╛рд░реНрдпрдХреНрд░рдо рдЕрдкрдорд╛рдирдЬрдирдХ рд╣реИ - рд╣рдо рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ 2 рдкрдВрдХреНрддрд┐рдпреЛрдВ рдореЗрдВ рдкреНрд░рд╡реЗрд╢ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╣рддреЗ рд╣реИрдВ, рдФрд░ рдлрд┐рд░ рдЧрдгрдирд╛ рдХрд╛ рдкрд░рд┐рдгрд╛рдо рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддреЗ рд╣реИрдВред
рд╣рдо рджреЗрдЦрддреЗ рд╣реИрдВ рдХрд┐ рд╣рдорд╛рд░реЗ рдлрд╝рдВрдХреНрд╢рди рдлреВ рдХреЛ рдЕрднреА рддрдХ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ (рдпрд╣ рд╣рдореЗрд╢рд╛ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХреЛ рдХреНрд░реИрд╢ рдХрд░рдиреЗ рдХрд╛ рдХрд╛рд░рдг рдмрдирддрд╛ рд╣реИ), рд╣рд╛рд▓рд╛рдВрдХрд┐ рд╣рд╛рд╕реНрдХреЗрд▓ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд╣рдорд╛рд░реЗ рдХреЛрдб рдХреЛ рд╕рдВрдХрд▓рд┐рдд рдХрд░ рд╕рдХрддрд╛ рд╣реИред

рдЕрдм рд╣рдо рдЕрдкрдиреЗ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдФрд░ рдЕрдзрд┐рдХ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рд▓рд┐рдЦрддреЗ рд╣реИрдВ, рдХреЗрд╡рд▓ "рд╕реНрд╡рдЪреНрдЫ" рдбреЗрдЯрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП:
 pure1arg :: Int -> Int pure1arg = (+ 1) --   ,   1  pure2args :: Int -> Int -> Int pure2args = (+) --  ,   2  unsafe2args :: Int -> Int -> Int unsafe2args = div --   ,   2  foo :: String -> String -> Int foo ab = unsafe2args extraUnsafeE unsafeC --     ,     where unsafeA :: Int unsafeA = read a --           unsafeB :: Int unsafeB = read b --  unsafeA    unsafeC :: Int unsafeC = pure1arg unsafeB --    1     reallyUnsafeD :: Int reallyUnsafeD = pure2args unsafeA unsafeC --    2     extraUnsafeE :: Int extraUnsafeE = unsafe2args unsafeA reallyUnsafeD --    2 .  2   . 

рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдпрд╣ рднреА рдпрд╣рд╛рдБ рд╕реНрдкрд╖реНрдЯ рд╣реИ, рдлрд╝рдВрдХреНрд╢рди foo рдЕрдирд┐рд╡рд╛рд░реНрдп рд░реВрдк рд╕реЗ [рдХреЛрдИ рдлрд░реНрдХ рдирд╣реАрдВ рдкрдбрд╝рддрд╛] рдкреВрд░реНрдгрд╛рдВрдХ рд╡рд┐рднрд╛рдЬрди рдФрд░ рд░рдХрдо рдХрд╛ рдорд┐рд╢реНрд░рдг рд╣реИред
рдЕрдзрд┐рдХрд╛рдВрд╢ рдХрд╛рд░реНрдпрд╛рддреНрдордХ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рднрд╛рд╖рд╛рдПрдВ рд╕реНрд╡рдЪреНрдЫ рдбреЗрдЯрд╛ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдлрд╝рдВрдХреНрд╢рди рдмрдирд╛рдирд╛ рдЖрд╕рд╛рди рдФрд░ рд╕рд░рд▓ рдмрдирд╛рддреА рд╣реИрдВред

рд╕рдм рдХреБрдЫ рдЕрджреНрднреБрдд рдкреНрд░рддреАрдд рд╣реЛрдЧрд╛ - рдПрдХ рд╕рд░рд▓ рдФрд░ рд╕реБрд░реБрдЪрд┐рдкреВрд░реНрдг рдХрд╛рд░реНрдпрдХреНрд░рдоред рд▓реЗрдХрд┐рди рдиреЗрдЯрдХреА!
рдлрдВрдХреНрд╢рди рдХрд╛ рдкрд░рд┐рдгрд╛рдо рдЬрд┐рддрдирд╛ рд╣рдо рдЪрд╛рд╣рддреЗ рд╣реИрдВ рдЙрд╕рд╕реЗ рдХрд╣реАрдВ рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рд╣реИред
рдЬреИрд╕рд╛ рдХрд┐ рд╣рдо рд╕рдордЭрддреЗ рд╣реИрдВ, 0 рд╕реЗ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░рдирд╛ рдЕрд╕рдВрднрд╡ рд╣реИ, рдФрд░ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╕рдВрдЦреНрдпрд╛рдУрдВ рдореЗрдВ рдирд╣реАрдВ, рдмрд▓реНрдХрд┐ рдмрд╛рдПрдВ рддрд╛рд░реЛрдВ рдореЗрдВ рдкреНрд░рд╡реЗрд╢ рдХрд░ рд╕рдХрддрд╛ рд╣реИ, рдФрд░ рдЬрдм рддрд╛рд░реЛрдВ рдХреЛ рд╕рдВрдЦреНрдпрд╛рдУрдВ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд░ рд╕рдХрддрд╛ рд╣реИ, рддреЛ рд╡рд╣ рдПрдХ рддреНрд░реБрдЯрд┐ рдлреЗрдВрдХ рд╕рдХрддрд╛ рд╣реИред рд╣рдорд╛рд░рд╛ рдХреЛрдб рдЕрд╕реБрд░рдХреНрд╖рд┐рдд рд╣реЛ рдЧрдпрд╛ред
рдРрд╕реА рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдирд┐рд╡рд╛рд░реНрдп рджреГрд╖реНрдЯрд┐рдХреЛрдг 2 рд╕рдореВрд╣реЛрдВ рдореЗрдВ рд╡рд┐рднрд╛рдЬрд┐рдд рд╣реИ: рдпрд╛ рддреЛ рд╢рд╛рдЦрд╛рдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ, рдпрд╛ рдЕрдкрд╡рд╛рджреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВред рдЕрдХреНрд╕рд░, рджреЛрдиреЛрдВ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╕рдВрдпреБрдХреНрдд рд╣реЛрддреЗ рд╣реИрдВред
рдпреЗ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдЗрддрдиреЗ рдкреНрд░рднрд╛рд╡реА рд╣реИрдВ рдХрд┐ рд╡реЗ рдореБрдЦреНрдп рд░реВрдк рд╕реЗ рдХрд╛рд░реНрдпрд╛рддреНрдордХ рднрд╛рд╖рд╛рдУрдВ рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВред
рдЖрдЗрдП рдЗрд╕рдХрд╛ рд╕рд╛рдордирд╛ рдХрд░рддреЗ рд╣реИрдВ - рд╣рд╛рд╕реНрдХреЗрд▓ рдореЗрдВ рдЕрдкрд╡рд╛рдж рд╣реИрдВ, рд▓реЗрдХрд┐рди рд╡реЗ рдЕрд╡рд┐рдХрд╕рд┐рдд рд╣реИрдВ, рдЙрдиреНрд╣реЗрдВ рд╕реБрдзрд╛рд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдФрд░ рд╕рдмрд╕реЗ рдЕрдЪреНрдЫреЗ рддрд░реАрдХреЗ рд╕реЗ рдирд╣реАрдВ рдкрдХрдбрд╝рд╛ рдЧрдпрд╛ рд╣реИред рдФрд░ рд╕рдмрд╕реЗ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдмрд╛рдд - рдЬреНрдпрд╛рджрд╛рддрд░ рдорд╛рдорд▓реЛрдВ рдореЗрдВ рд╡реЗ рдмрд╕ рдЬрд░реВрд░рдд рдирд╣реАрдВ рд╣реИред
рд▓реЗрдХрд┐рди рдХрдо рдирд╣реАрдВ - рдпрд╣ рд╕рдВрднрд╡ рд╣реИред
рдЗрд╕рд▓рд┐рдП, рд╣рдо рд╢рд╛рдЦрд╛рдУрдВ рдФрд░ рдЕрдкрд╡рд╛рджреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЕрдкрдиреЗ рдХреЛрдб рдХреЛ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦрдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░реЗрдВрдЧреЗред
 module Main where import Control.Exception (IOException, catch) printError :: IOException -> IO () printError = print pure2args :: Int -> Int -> Int pure2args = (+) pure1arg :: Int -> Int pure1arg = (+ 1) unsafe2args :: Int -> Int -> Int unsafe2args ab = if b == 0 then error "Error 'unsafe2args' : wrong 2nd argument = 0" --unsafe source of IOException else div ab foo :: String -> String -> Int foo ab = unsafe2args extraUnsafeE unsafeC where unsafeA :: Int unsafeA = read a --unsafe source of IOException unsafeB :: Int unsafeB = read b --unsafe source of IOException unsafeC :: Int unsafeC = pure1arg unsafeB reallyUnsafeD :: Int reallyUnsafeD = pure2args unsafeA unsafeC extraUnsafeE :: Int extraUnsafeE = unsafe2args unsafeA reallyUnsafeD main :: IO () main = do putStrLn "Input a: " a <- getLine putStrLn "Input b: " b <- getLine catch (print (foo ab)) printError --      IOException 

рдЧрдВрджрд╛ рдбреЗрдЯрд╛


рд╣рд╛рд╕реНрдХреЗрд▓ (рдФрд░ рдХрдИ рдХрд╛рд░реНрдпрд╛рддреНрдордХ рднрд╛рд╖рд╛рдУрдВ) рдореЗрдВ рдРрд╕реА рд╕рдорд╕реНрдпрд╛рдУрдВ рдХрд╛ рдПрдХ рдпреЛрдЧреНрдп рдЬрд╡рд╛рдм рд╣реИред
рдореБрдЦреНрдп рддрд╛рдХрдд рдмреАрдЬрдЧрдгрд┐рддреАрдп рдбреЗрдЯрд╛ рдкреНрд░рдХрд╛рд░реЛрдВ рдореЗрдВ рдирд┐рд╣рд┐рдд рд╣реИред

рдпрджрд┐ рд╣рдо рдЙрдкрд░реЛрдХреНрдд рдЙрджрд╛рд╣рд░рдг рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдпрд╣ рд╕реНрдкрд╖реНрдЯ рд╣реИ рдХрд┐ рд╣рдорд╛рд░реЗ рдХрд╛рд░реНрдп рдЧрд┐рд░ рд╕рдХрддреЗ рд╣реИрдВред
рд╕рдорд╛рдзрд╛рди рдЕрд╢рдХреНрдд рдбреЗрдЯрд╛ рдкреНрд░рдХрд╛рд░реЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╣реИред
рдПрдордПрд▓ рднрд╛рд╖рд╛рдУрдВ рдФрд░ рд╕реНрдХрд╛рд▓рд╛ рдореЗрдВ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдХреЛ Option рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ, рд╣рд╛рд╕реНрдХреЗрд▓ рдореЗрдВ рдЗрд╕реЗ Maybe a рдХрд╣рд╛ рдЬрд╛рддрд╛ Maybe a ред
 import Prelude hiding (Maybe) --       .       data Maybe a = Nothing | Just a deriving Show 

рд╣рдо deriving рд╣рд┐рд╕реНрд╕реЗ рдкрд░ рдзреНрдпрд╛рди рдирд╣реАрдВ рджреЗрддреЗ рд╣реИрдВ, рд╣рдо рд╕рд┐рд░реНрдл рдпрд╣ рдХрд╣рддреЗ рд╣реИрдВ рдХрд┐ рд╣рдо рдХрдВрдкрд╛рдЗрд▓рд░ рдХреЛ рдЕрдкрдиреЗ рдбреЗрдЯрд╛ рдЯрд╛рдЗрдк рдХреЛ рдЕрдкрдиреЗ рджрдо рдкрд░ рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдореЗрдВ рдЕрдиреБрд╡рд╛рдж рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╣рддреЗ рд╣реИрдВред
рдЕрд░реНрдерд╛рддреН,
 show Nothing == "Nothing" show (Just 3) == "Just 3" 

рдпрджрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдбреЗрдЯрд╛ рдирд╣реАрдВ рд╣реИ, рддреЛ рдбреЗрдЯрд╛ рдкреНрд░рдХрд╛рд░ Nothing рдирд╣реАрдВ рд╣реИ, рдФрд░ рдпрджрд┐ рдпрд╣ рд╣реИ рддреЛ Just a ред
рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдбреЗрдЯрд╛ рдкреНрд░рдХрд╛рд░ "рдЧрдВрджрд╛" рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдЗрд╕рдореЗрдВ рдЕрдирд╛рд╡рд╢реНрдпрдХ рдЬрд╛рдирдХрд╛рд░реА рд╢рд╛рдорд┐рд▓ рд╣реИред
рдЖрдЗрдП рд╣рдорд╛рд░реЗ рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдЕрдзрд┐рдХ рд╕рд╣реА рдврдВрдЧ рд╕реЗ, рдЕрдзрд┐рдХ рд╕реБрд░рдХреНрд╖рд┐рдд рдФрд░ рдмрд┐рдирд╛ рдХрд┐рд╕реА рдЕрдкрд╡рд╛рдж рдХреЗ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦреЗрдВред

рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╣рдо рдЙрди рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдЬреЛ рд╕реБрд░рдХреНрд╖рд┐рдд рдПрдирд╛рд▓реЙрдЧреНрд╕ рдХреЗ рдкрддрди рдХрд╛ рдХрд╛рд░рдг рдмрдиреЗ:
 maybeResult2args :: Int -> Int -> Maybe Int maybeResult2args ab = if b == 0 then Nothing --safe else Just (div ab) ... maybeA :: Maybe Int maybeA = readMaybe a --safe maybeB :: Maybe Int maybeB = readMaybe b --safe 

рдЕрдм рдЧрд┐рд░рдиреЗ рдХреЗ рдмрдЬрд╛рдп рдпреЗ рдХрд╛рд░реНрдп рдкрд░рд┐рдгрд╛рдо рджреЗрддреЗ рд╣реИрдВ Nothing , рдпрджрд┐ рд╕рдм рдХреБрдЫ рдХреНрд░рдо рдореЗрдВ рд╣реИ, рддреЛ Just ред

рд▓реЗрдХрд┐рди рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдмрд╛рдХреА рдХреЛрдб рдЗрди рдХрд╛рд░реНрдпреЛрдВ рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддреЗ рд╣реИрдВред рд╣рдореЗрдВ рд▓рдЧрднрдЧ рд╕рднреА рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдмрджрд▓рдирд╛ рд╣реЛрдЧрд╛, рдЬрд┐рдирдореЗрдВ рдХрдИ рдмрд╛рд░ рдкрд░реАрдХреНрд╖рдг рдХрд┐рдП рдЧрдП рд╣реИрдВред
 pure2args :: Int -> Int -> Int pure2args = (+) safePure2args :: Maybe Int -> Maybe Int -> Maybe Int safePure2args ab = case a of Nothing -> Nothing Just a' -> case b of Nothing -> Nothing Just b' -> Just (pure2args a' b') pure1arg :: Int -> Int pure1arg = (+ 1) safePure1arg :: Maybe Int -> Maybe Int safePure1arg a = case a of Nothing -> Nothing Just a' -> Just (pure1arg a') maybeResult2args :: Int -> Int -> Maybe Int maybeResult2args ab = if b == 0 then Nothing else Just (div ab) foo :: String -> String -> Maybe Int foo ab = case maybeE of Nothing -> Nothing Just e -> case maybeC of Nothing -> Nothing Just c -> maybeResult2args ec where maybeA :: Maybe Int maybeA = readMaybe a maybeB :: Maybe Int maybeB = readMaybe b maybeC :: Maybe Int maybeC = safePure1arg maybeB maybeD :: Maybe Int maybeD = safePure2args maybeA maybeC maybeE = case maybeA of Nothing -> Nothing Just a1 -> case maybeD of Nothing -> Nothing Just d -> maybeResult2args a1 d printMaybe :: Show a => Maybe a -> IO () printMaybe Nothing = print "Something Wrong" printMaybe (Just a) = print a main :: IO () main = do putStrLn "Input a: " a <- getLine putStrLn "Input b: " b <- getLine printMaybe (foo ab) 

рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдПрдХ рд╕рд╛рдзрд╛рд░рдг рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХрд╛рдлреА рд░рд╛рдХреНрд╖рд╕ рдЬреИрд╕рд╛ рдХреЛрдб рдмрди рдЧрдпрд╛ рд╣реИред
рдмрд╣реБрдд рд╕рд╛рд░реЗ рд░реИрдкрд░ рдлрд╝рдВрдХреНрд╢рди, рдмрд╣реБрдд рд╕рд╛рд░реЗ рдЕрдирд╛рд╡рд╢реНрдпрдХ рдХреЛрдб, рдмрд╣реБрдд рд╕рд╛рд░реЗ рдмрджрд▓рд╛рд╡ред
рд▓реЗрдХрд┐рди рдпрд╣ рдареАрдХ рд╡рд╣реА рд╣реИ рдЬрд╣рд╛рдВ рдХрдИ рдХрд╛рд░реНрдпрд╛рддреНрдордХ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рднрд╛рд╖рд╛рдПрдВ рдмрдВрдж рд╣реЛ рдЬрд╛рддреА рд╣реИрдВред
рдЕрдм рдЖрдк рд╕рдордЭ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдЙрди рднрд╛рд╖рд╛рдУрдВ рдореЗрдВ рдХреНрдпреЛрдВ, рдХрдИ рдПрдбреАрдЯреА рдмрдирд╛рдиреЗ рдХреА рд╕рдВрднрд╛рд╡рдирд╛ рдХреЗ рдмрд╛рд╡рдЬреВрдж, рдПрдбреАрдЯреА рдЗрддрдиреА рдмрд╛рд░ рдХреЛрдб рдореЗрдВ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВред

рдХреНрдпрд╛ рдореИрдВ рдПрдбреАрдЯреА рдХреЗ рд╕рд╛рде рд░рд╣ рд╕рдХрддрд╛ рд╣реВрдВ, рд▓реЗрдХрд┐рди рд╕рдорд╛рди рдмреИрдЪреИрдирд▓рд┐рдпрд╛ рдХреЗ рдмрд┐рдирд╛? рдпрд╣ рдЖрдк рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдкрддрд╛ рдЪрд▓рд╛ рд╣реИред

functors


рд╢реБрд░реБрдЖрдд рдореЗрдВ, рдлрдВрдХреНрд╢рдВрд╕ рдмрдЪрд╛рд╡ рдХреЗ рд▓рд┐рдП рдЖрддреЗ рд╣реИрдВред

рдлрдВрдбрд░реНрд╕ рд╡реЗ рдбреЗрдЯрд╛ рдкреНрд░рдХрд╛рд░ рд╣реЛрддреЗ рд╣реИрдВ рдЬрд┐рдирдХреЗ рд▓рд┐рдП fmap рдлрд╝рдВрдХреНрд╢рди рдореМрдЬреВрдж рд╣реЛрддрд╛ рд╣реИред
 class Functor f where fmap :: (a -> b) -> fa -> fb 

рдФрд░ рд╕рд╛рде рд╣реА рдЗрд╕рдХреЗ infix рдкрд░реНрдпрд╛рдп:
 (<$>) :: Functor f => (a -> b) -> fa -> fb (<$>) = fmap 

рдбреЗрдЯрд╛ рдХреЗ рд╕рднреА рдорд╛рдиреЛрдВ рдХреЗ рд▓рд┐рдП рдирд┐рдореНрди рд╕реНрдерд┐рддрд┐рдпрд╛рдБ рд╣рдореЗрд╢рд╛ рд╕рдВрддреБрд╖реНрдЯ рд░рд╣рддреА рд╣реИрдВ:

рдкрд╣рдЪрд╛рди рдХреА рд╕реНрдерд┐рддрд┐:
fmap id == id
рд░рдЪрдирд╛ рдХреА рд╕реНрдерд┐рддрд┐:
fmap (f . g) == fmap f . fmap g

рдЬрд╣рд╛рдВ id рдПрдХ рдкрд╣рдЪрд╛рди рд╕рдорд╛рд░реЛрд╣ рд╣реИ
  id :: a -> a id x = x 

рдФрд░ (.) - рдХрд╛рд░реНрдпрд╛рддреНрдордХ рд░рдЪрдирд╛
  (.) :: (b -> c) -> (a -> b) -> a -> c f . g = \x -> f (gx) 

рдПрдХ fmap рдПрдХ рдкреНрд░рдХрд╛рд░ рдХрд╛ рд╡рд░реНрдЧ рд╣реИ, рдЬрд╣рд╛рдБ рд╣рдордиреЗ рдПрдХ рд╡рд┐рд╢реЗрд╖ fmap рдлрдВрдХреНрд╢рди рдмрдирд╛рдпрд╛ рд╣реИред рдЖрдЗрдП рдЙрд╕рдХреЗ рддрд░реНрдХреЛрдВ рдкрд░ рдЧреМрд░ рдХрд░реЗрдВ - рд╡рд╣ рдПрдХ "рд╕рд╛рдл" рдлрд╝рдВрдХреНрд╢рди a -> b рд▓реЗрддрд╛ рд╣реИ, рд╣рдо "рдЧрдВрджреЗ" рдлрдВрдХреНрд╢рдирд▓ рд╡реИрд▓реНрдпреВ рдлрд╛рджрд░ рд▓реЗрддреЗ рд╣реИрдВ рдФрд░ рд╣рдо рдЖрдЙрдЯрдкреБрдЯ рдкрд░ рдлрдВрдХреНрдЯрд░ рдореВрд▓реНрдп fb рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВред

Maybe рдбреЗрдЯрд╛ рдкреНрд░рдХрд╛рд░ рдПрдХ рдлрд╝рдирдХрд╛рд░ рд╣реИред Maybe рдкреНрд░рдХрд╛рд░ рдХреЗ рд▓рд┐рдП рдПрдХ рдЙрджрд╛рд╣рд░рдг (рдЙрджрд╛рд╣рд░рдг) рдмрдирд╛рддреЗ рд╣реИрдВ, рддрд╛рдХрд┐ рдлрдВрдХреНрд╢рдВрд╕ рдХреЗ рдирд┐рдпрдореЛрдВ рдХрд╛ рдЙрд▓реНрд▓рдВрдШрди рди рд╣реЛ:
 instance Functor Maybe where fmap _ Nothing = Nothing fmap f (Just a) = Just (fa) 

рд╣рдо Maybe рдПрдХ рдлрд╝реНрдпреВрдЪрд░ рдХреЗ рд╕рд╛рде рдПрдХ рд╢реБрджреНрдз рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреИрд╕реЗ рдХрд░рддреЗ рд╣реИрдВ? рдмрд╣реБрдд рд╕рд░рд▓:
 safePure1arg :: Maybe Int -> Maybe Int safePure1arg = fmap pure1arg 

рд╣рдо рдпрд╣рд╛рдВ рдореБрдЦреНрдп рдмрд╛рдд рджреЗрдЦрддреЗ рд╣реИрдВ - рд╣рдордиреЗ рдЕрдкрдиреЗ pure1arg рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдлрд┐рд░ рд╕реЗ рдирд╣реАрдВ pure1arg рд╣реИ, рдЬрд┐рд╕рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐ рд╣рдореЗрдВ рдЗрд╕реЗ рдХреАрдбрд╝реЗ рдХреЗ рд▓рд┐рдП рдлрд┐рд░ рд╕реЗ рдкрд░реАрдХреНрд╖рдг рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ рдФрд░ рдЗрд╕ рд╕рдм рдХреЗ рд▓рд┐рдП, рдпрд╣ рд╕рд╛рд░реНрд╡рднреМрдорд┐рдХ рдФрд░ рд╕реНрд╡рдЪреНрдЫ рд░рд╣рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рд╣рдордиреЗ рдЖрд╕рд╛рдиреА рд╕реЗ рдЗрд╕рдХрд╛ рд╕реБрд░рдХреНрд╖рд┐рдд рд╕рдВрд╕реНрдХрд░рдг рдмрдирд╛рдпрд╛, рдЬреЛ рд╕рдВрдЦреНрдпрд╛рдУрдВ рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЕрд╢рдХреНрдд рд╣реИрдВ рдирдВрдмрд░ред

рд╣рд╛рд▓рд╛рдБрдХрд┐, рдЕрдЧрд░ рд╣рдо safePure2args рдХреЛ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦрдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░рддреЗ рд╣реБрдП рдПрдХ safePure2args рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рд╣рдо рдЕрд╕рдлрд▓ рд╣реЛрдВрдЧреЗред
рдлрд╝рдирдХрд╛рд░ рдХреЗрд╡рд▓ рдПрдХ рдлрд╝рдирдХрд╛рд░-рдЧрдВрджреЗ рддрд░реНрдХ рд╡рд╛рд▓реЗ рдлрд╝рдВрдХреНрд╢рдВрд╕ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВред
рдХрдИ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рдХреНрдпрд╛ рдХрд░рдирд╛ рд╣реИ?

рдПрдкреНрд▓рд╛рдЗрдб рдлрдВрдХреНрд╢рдирд▓рд░реНрд╕


рдпрд╣рд╛рдБ рдЖрд╡реЗрджрдХ рдлрдВрдХреНрд╢рдиреНрд╕ рд╣рдорд╛рд░реА рд╕рд╣рд╛рдпрддрд╛ рдХреЗ рд▓рд┐рдП рдЖрддреЗ рд╣реИрдВ:

рд╡реНрдпрд╛рд╡рд╣рд╛рд░рд┐рдХ рдлрдВрдХреНрд╢рдирд▓рд░реНрд╕ рд╡реЗ рдлрдВрдХреНрд╢рдирд▓рд░реНрд╕ рд╣реИрдВ рдЬрд┐рдирдХреЗ рд▓рд┐рдП 2 рдлрд╝рдВрдХреНрд╢рдВрд╕ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдП рдЧрдП рд╣реИрдВ: pure рдФрд░ (<*>)
 class Functor f => Applicative f where pure :: a -> fa (<*>) :: f (a -> b) -> fa -> fb 

рдЙрдирдХреЗ рд▓рд┐рдП рд╕рдорд╛рди рдбреЗрдЯрд╛ рдХреЗ рдХрд┐рд╕реА рднреА рдорд╛рди рдХреЗ рд▓рд┐рдП рдирд┐рдореНрди рдирд┐рдпрдо рд╣рдореЗрд╢рд╛ рд╕рд╣реА рд╣реЛрддреЗ рд╣реИрдВ:

рдкрд╣рдЪрд╛рди рдХреА рд╕реНрдерд┐рддрд┐:
pure id <*> v == v
рд░рдЪрдирд╛ рдХреА рд╕реНрдерд┐рддрд┐:
pure (.) <*> u <*> v <*> w == u <*> (v <*> w)
рд╣реЛрдореЛрдореЛрд░реНрдлрд┐рдЬреНрдо рдХреА рд╕реНрдерд┐рддрд┐:
pure f <*> pure x == pure (fx)
рд╡рд┐рдирд┐рдордп рд╕реНрдерд┐рддрд┐:
u <*> pure y == pure ($ y) <*> u

рдлрд╝рдВрдХреНрдЯрд░ рдФрд░ рдПрдкреЗрдХреНрдЯрд┐рд╡ рдлрд╝рдВрдХреНрдЯрд░ рдХреЗ рдмреАрдЪ рдореБрдЦреНрдп рдЕрдВрддрд░ рдпрд╣ рд╣реИ рдХрд┐ рдлрд╝рдВрдХреНрдЯрд░, рдлрд╝реНрдпреВрдЪрд░ рд╡реИрд▓реНрдпреВ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдПрдХ рд╢реБрджреНрдз рдХрд╛рд░реНрдп рдХрд░рддрд╛ рд╣реИ, рдЬрдмрдХрд┐ рдПрдкреНрд▓рд┐рдХреЗрд░ рдлрд╝рдВрдХреНрдЯрд░ рд╣рдореЗрдВ рдлрд╝рдВрдХреНрдЯрд░ рдореВрд▓реНрдп рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдлрд╝рдВрдХреНрдЯрд░ рдлрд╝рдВрдХреНрд╢рди f (a -> b) рдХреЛ рдЦреАрдВрдЪрдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред

рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рдПрдХ рдРрдкреНрд▓рд┐рдХреЗрдЯрд░ рдлрд╝рдВрдХреНрдЯрд░ рд╣реИ рдФрд░ рдЗрд╕реЗ рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ:
 instance Applicative Maybe where pure = Just Nothing <*> _ = Nothing _ <*> Nothing = Nothing (Just f) <*> (Just a) = Just (fa) 

safePure2args рдХреЛ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦрдиреЗ рдХрд╛ рд╕рдордп рдЖ рдЧрдпрд╛ рд╣реИред
рдореВрд▓ рд░реВрдк рд╕реЗ, рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдкрд╣рд▓реЗ рддрд░реНрдХ рдХреЗ рд▓рд┐рдП fmap рд╕рдВрдпреЛрдЬрди, рдФрд░ рд╢реЗрд╖ рддрд░реНрдХреЛрдВ рдХрд╛ рдЖрд╡реЗрджрди рд╕реНрдЯреНрд░рд┐рдВрдЧ:
 safePure2args :: Maybe Int -> Maybe Int -> Maybe Int safePure2args ab = pure2args <$> a <*> b 

рд▓реЗрдХрд┐рди рдЖрдк рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдкреНрд░рдпреЛрдЬрдХреАрдп рдХрд╛рд░реНрдпреЛрдВ (рд╕рдирдХ рд╢реИрд▓реА) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВ - рдкрд╣рд▓реЗ рд╣рдо рдПрдХ "рд╢реБрджреНрдз" рдлрд╝рдВрдХреНрд╢рди рдХреЛ рд╢реБрджреНрдз рд░реВрдк рд╕реЗ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рддрд░реНрдХ рдХреЛ рддрд╛рд░реНрдХрд┐рдХ рд░реВрдк рд╕реЗ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХрд░рддреЗ рд╣реИрдВ:
 safePure2args :: Maybe Int -> Maybe Int -> Maybe Int safePure2args ab = (pure pure2args) <*> a <*> b 

рдЕрджреНрднреБрдд!
рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рд╣рдо рдПрдХ рд╣реА рд╕рдордп рдореЗрдВ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ maybeE рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╢рд╛рдпрдж maybeE рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдлрд┐рд░ рд╕реЗ maybeE ? рдЕрдлрд╕реЛрд╕ред

рдЗрдХрд╛рдИ


рдЪрд▓реЛ maybeResult2args рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рдкрд░ рдзреНрдпрд╛рди рджреЗрдВ:
maybeResult2args :: Int -> Int -> Maybe Int
рдлрд╝рдВрдХреНрд╢рди рдЗрдирдкреБрдЯ рдХреЗ рд░реВрдк рдореЗрдВ "рдХреНрд▓реАрди" рддрд░реНрдХ рд▓реЗрддрд╛ рд╣реИ, рдФрд░ рдЖрдЙрдЯрдкреБрдЯ рдкрд░ "рдЧрдВрджреЗ" рдкрд░рд┐рдгрд╛рдо рдкреИрджрд╛ рдХрд░рддрд╛ рд╣реИред
рдЗрд╕рд▓рд┐рдП, рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдореЗрдВ рдЕрдзрд┐рдХрд╛рдВрд╢ рднрд╛рдЧ рдХреЗ рд▓рд┐рдП, рдпрд╣ рдареАрдХ рдРрд╕реЗ рдХрд╛рд░реНрдп рд╣реИрдВ рдЬреЛ рдЕрдХреНрд╕рд░ рд╕рд╛рдордирд╛ рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ - рд╡реЗ рдЗрдирдкреБрдЯ рдХреЗ рд░реВрдк рдореЗрдВ "рд╢реБрджреНрдз" рддрд░реНрдХ рд▓реЗрддреЗ рд╣реИрдВ, рдФрд░ рдкрд░рд┐рдгрд╛рдо "рдЧрдВрджрд╛" рд╣реИред
рдФрд░ рдЬрдм рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдХрдИ рдРрд╕реЗ рдХрд╛рд░реНрдп рд╣реЛрддреЗ рд╣реИрдВ, рддреЛ рдорда рдЙрдиреНрд╣реЗрдВ рдПрдХ рд╕рд╛рде рдорд┐рд▓рд╛рдиреЗ рдореЗрдВ рдорджрдж рдХрд░рддреЗ рд╣реИрдВред

рдореЛрдирд╛рдбреНрд╕ рдбреЗрдЯрд╛ рдкреНрд░рдХрд╛рд░ рд╣реИрдВ рдЬрд┐рд╕рдХреЗ рд▓рд┐рдП return рдФрд░ (>>=) рдлрд╝рдВрдХреНрд╢рди рдореМрдЬреВрдж рд╣реИрдВред
 class Monad m where return :: a -> ma (>>=) :: ma -> (a -> mb) -> mb 

рдЗрд╕ рддрд░рд╣ рдХреЗ рдирд┐рдпрдо рдХрд┐рд╕реА рднреА рдкреНрд░рдХрд╛рд░ рдХреЗ рдореВрд▓реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рд╕рдВрддреБрд╖реНрдЯ рд╣реИрдВ:

рдмрд╛рдИрдВ рдкрд╣рдЪрд╛рди:
return a >>= k == ka
рд╕рд╣реА рдкрд╣рдЪрд╛рди:
m >>= return == m
рд╕рдВрдмрджреНрдзрддрд╛:
m >>= (\x -> kx >>= h) == (m >>= k) >>= h

рд╕реБрд╡рд┐рдзрд╛ рдХреЗ рд▓рд┐рдП, рддрд░реНрдХреЛрдВ рдХреЗ рд░рд┐рд╡рд░реНрд╕ рдСрд░реНрдбрд░ рдХреЗ рд╕рд╛рде рдПрдХ рдЕрддрд┐рд░рд┐рдХреНрдд рдХрд╛рд░реНрдп рд╣реИ:
 (=<<) :: Monad m => (a -> mb) -> ma -> mb (=<<) = flip (>>=) 

рдЬрд╣рд╛рдБ
 flip :: (a -> b -> c) -> b -> a -> c flip fab = fba 

рд╣рдо рд╕рдордЭрддреЗ рд╣реИрдВ рдХрд┐ Maybe рдкреНрд░рдХрд╛рд░ рдПрдХ рд╕рдиреНрдпрд╛рд╕реА рд╣реИ, рдЬрд┐рд╕рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐ рд╣рдо рдЗрд╕рдХреЗ рдЙрджрд╛рд╣рд░рдг (рдЙрджрд╛рд╣рд░рдг) рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:
 instance Monad Maybe where return = Just (Just x) >>= k = kx Nothing >>= _ = Nothing 

рд╡реИрд╕реЗ, рдЕрдЧрд░ рд╣рдо рдЖрдВрддрд░рд┐рдХ рд╕рд╛рдордЧреНрд░реА рдФрд░ рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рдкрд░ рдХрд░реАрдм рд╕реЗ рдирдЬрд╝рд░ рдбрд╛рд▓реЗрдВ, рддреЛ рд╣рдо рджреЗрдЦреЗрдВрдЧреЗ рдХрд┐:
pure == return
fmap f xs == xs >>= return . f

рдпрд╣ maybeE рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦрдиреЗ рдХрд╛ рд╕рдордп рд╣реИ
  maybeE = maybeA >>= (\a1 -> maybeD >>= (maybeResult2args a1)) 

рд╣рд╛рдБ, рдпрд╣ рдЕрдзрд┐рдХ рд╕реБрдВрджрд░ рдирд╣реАрдВ рдирд┐рдХрд▓рд╛ред рдРрд╕рд╛ рдЗрд╕рд▓рд┐рдП рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдПрдХ рдЪрд░ рдХреЗ рд▓рд┐рдП рднрд┐рдХреНрд╖реБрдУрдВ рдХреЛ рдЦреВрдмрд╕реВрд░рддреА рд╕реЗ рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рд╣реИред рд╕реМрднрд╛рдЧреНрдп рд╕реЗ, рдХрдИ рдЕрддрд┐рд░рд┐рдХреНрдд рд╡рд┐рд╢реЗрд╖рддрд╛рдПрдВ рд╣реИрдВред
рдЖрдк рдПрдХ bind2 рдлрд╝рдВрдХреНрд╢рди рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВ
 bind2 :: Monad m => (a -> b -> mc) -> ma -> mb -> mc bind2 mf mx my = do x <- mx y <- my mf xy 

  maybeE = bind2 maybeResult2args maybeA maybeD 

рдпрд╛ рдлрд╝рдВрдХреНрд╢рди liftM2 рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ рдФрд░ join
 liftM2 :: Monad m => (a1 -> a2 -> r) -> m a1 -> m a2 -> mr join :: Monad m => m (ma) -> ma maybeE = join $ liftM2 maybeResult2args maybeA maybeD 

рдЪрд░рдо рдорд╛рдорд▓реЛрдВ рдореЗрдВ, рдЖрдк рдиреЛрдЯреЗрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП рдореЛрдирд╛рдб рдХреЗ рд▓рд┐рдП рд╕рд┐рдВрдЯреИрдХреНрдЯрд┐рдХ рд╢реБрдЧрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:
  maybeE = do a1 <- maybeA d <- maybeD maybeResult2args a1 d 

рдкрд╛рдЙрдВрдб рдФрд░ рдореЛрдирдб рдХреЗ рдЙрдкрдпреЛрдЧ рдореЗрдВ рдЕрдВрддрд░


рдпрджрд┐ рд╣рдо рдореБрдЦреНрдп рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдПрдХ рд░реВрдк рдореЗрдВ рдШрдЯрд╛рддреЗ рд╣реИрдВ, рддреЛ рд╣рдо рджреЗрдЦреЗрдВрдЧреЗ:
 (<$>) :: Functor f => (a -> b) -> fa -> fb (<*>) :: Applicative f => f (a -> b) -> fa -> fb (=<<) :: Monad f => (a -> fb) -> fa -> fb 

рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рдЧрдВрджреЗ рдорд╛рдиреЛрдВ рдХреЛ рдкрд╛рд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рднреА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬрдмрдХрд┐ рдлрд╝рдВрдХреНрд╢рдВрд╕ рдЗрдирдкреБрдЯ рдкрд░ рд╕реНрд╡рдЪреНрдЫ рдореВрд▓реНрдпреЛрдВ рдХреА рдЕрдкреЗрдХреНрд╖рд╛ рдХрд░рддреЗ рд╣реИрдВред
рдлрдВрдбрд░реНрд╕ рдПрдХ "рдХреНрд▓реАрди" рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред
рдПрдкреНрд▓рд╛рдЗрдб рдлрдВрдХреНрд╢рдирд▓рд░реНрд╕ "рдкреНрд░рджреВрд╖рдг" рдХреЗ рднреАрддрд░ рдПрдХ "рд╢реБрджреНрдз" рдлрд╝рдВрдХреНрд╢рди рд╣реИрдВред
рдореЛрдирд╛рдбреНрд╕ рдРрд╕реЗ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ рдЬрд┐рдирдХреЗ рдЖрдЙрдЯрдкреБрдЯ рдкрд░ рдПрдХ рдЧрдВрджрд╛ рдЕрд░реНрде рд╣реИред

рджрд┐рдирдЪрд░реНрдпрд╛ рдХреЗ рдмрд┐рдирд╛ рдХрд╛рд░реНрдпрдХреНрд░рдо


рдЦреИрд░, рдЖрдЦрд┐рд░рдХрд╛рд░, рдЖрдк рдкреВрд░реЗ рдХрд╛рд░реНрдпрдХреНрд░рдо рдХреЛ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдФрд░ рд╕рдЯреАрдХ рд░реВрдк рд╕реЗ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВ:
 module Main where import Control.Monad import Control.Applicative import Text.Read (readMaybe) bind2 :: Monad m => (a -> b -> mc) -> ma -> mb -> mc bind2 mf mx my = do x <- mx y <- my mf xy pure2args :: Int -> Int -> Int pure2args = (+) pure1arg :: Int -> Int pure1arg = (+ 1) maybeResult2args :: Int -> Int -> Maybe Int maybeResult2args ab = if b == 0 then Nothing --safe else Just (div ab) foo :: String -> String -> Maybe Int foo ab = bind2 maybeResult2args maybeE maybeC where maybeA :: Maybe Int maybeA = readMaybe a --safe maybeB :: Maybe Int maybeB = readMaybe b --safe maybeC :: Maybe Int maybeC = fmap pure1arg maybeB maybeD :: Maybe Int maybeD = pure2args <$> maybeA <*> maybeC maybeE :: Maybe Int maybeE = bind2 maybeResult2args maybeA maybeD printMaybe :: Show a => Maybe a -> IO () printMaybe Nothing = print "Something Wrong" printMaybe (Just a) = print a main :: IO () main = do putStrLn "Input a: " a <- getLine putStrLn "Input b: " b <- getLine printMaybe (foo ab) 

рдХреЛрдб рдлрд┐рд░ рд╕реЗ рд╕рд░рд▓ рдФрд░ рд╕реНрдкрд╖реНрдЯ рд╣реЛ рдЧрдпрд╛!
рдЙрд╕реА рд╕рдордп, рд╣рдордиреЗ рд╕реБрд░рдХреНрд╖рд╛ рдХрд╛ рдПрдХ рдЗрдВрдЪ рднреА рдирд╣реАрдВ рдЫреЛрдбрд╝рд╛!
рд╣рд╛рд▓рд╛рдБрдХрд┐, рд╣рдордиреЗ рд▓рдЧрднрдЧ рдХреЛрдб рдирд╣реАрдВ рдмрджрд▓рд╛ рд╣реИ!
рдЙрд╕реА рд╕рдордп, рд╢реБрджреНрдз рдХрд╛рд░реНрдп рд╢реБрджреНрдз рдмрдиреЗ рд░рд╣реЗ!
рдЙрд╕реА рд╕рдордп, рджрд┐рдирдЪрд░реНрдпрд╛ рд╕реЗ рдмрдЪрд╛ рдЧрдпрд╛ рдерд╛!

рдирд┐рд╖реНрдХрд░реНрд╖


рдХреНрдпрд╛ рдпрд╣ рд╕рдВрднрд╡ рд╣реИ рдХрд┐ рдХрд╛рд░реНрдпрд╛рддреНрдордХ рдФрд░ рднрд┐рдХреНрд╖реБрдУрдВ рдХреЗ рдмрд┐рдирд╛ рдПрдХ рдХрд╛рд░реНрдпрд╛рддреНрдордХ рджреБрдирд┐рдпрд╛ рдореЗрдВ рд░рд╣рдирд╛ рд╕рдВрднрд╡ рд╣реИ? рдЖрдк рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
рд▓реЗрдХрд┐рди, рдЕрдЧрд░ рд╣рдо рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдмреАрдЬреАрдп рдбреЗрдЯрд╛ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреА рдкреВрд░реНрдг рд╢рдХреНрддрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рд╣рдореЗрдВ рд╡рд┐рднрд┐рдиреНрди рдХрд╛рд░реНрдпреЛрдВ рдХреА рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдХрд╛рд░реНрдпрд╛рддреНрдордХ рд╕рдВрд░рдЪрдирд╛ рдХреЗ рд▓рд┐рдП рдлрдВрдХреНрд╢рдирд▓рд░реНрд╕ рдФрд░ рдореЛрдирд╛рдбреНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред
рдпрд╣ рджрд┐рдирдЪрд░реНрдпрд╛ рдХреЗ рд▓рд┐рдП рдПрдХ рдЙрддреНрдХреГрд╖реНрдЯ рдЙрдкрд╛рдп рд╣реИ рдФрд░ рдПрдХ рд╕рдВрдХреНрд╖рд┐рдкреНрдд, рд╕рдордЭрдиреЗ рдпреЛрдЧреНрдп рдФрд░ рдЕрдХреНрд╕рд░ рдкреБрди: рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рдХреЛрдб рдХрд╛ рдПрдХ рддрд░реАрдХрд╛ рд╣реИ!

PS рдпрд╣ рд╕рдордЭрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП рдХрд┐ рд╡рд┐рднрд┐рдиреНрди рдкреНрд░рдХрд╛рд░ рдХреЗ рдбреЗрдЯрд╛ рдХреЗ рд▓рд┐рдП, "рд╕реНрд╡рдЪреНрдЫ" рдФрд░ "рдЧрдВрджреЗ" рдбреЗрдЯрд╛ рдкреНрд░рдХрд╛рд░ рдХреЗ рд╕рд╛рде рд╕рдорд╛рдирддрд╛ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдЙрдкрдпреБрдХреНрдд рдирд╣реАрдВ рд╣реИред
рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╕реВрдЪрд┐рдпреЛрдВ рдХреЗ рд▓рд┐рдП
fmap = map
рдПрдХ рднрд┐рдХреНрд╖реБ:
  a = do c <- cs d <- ds return (zet cd) 

рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рд╣реИ
 a = [zet cd | c <- cs, d <- ds] 

рдЬреЛ рдкрд╣рд▓реА рдирдЬрд░ рдореЗрдВ рд╣рдореЗрд╢рд╛ рд╕реНрдкрд╖реНрдЯ рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИред

Source: https://habr.com/ru/post/In212955/


All Articles