> import Prelude hiding (div,return,fmap) > import qualified Prelude ------------------------------------------------------------ Language E + div exception + monadic exception threading ------------------------------------------------------------ > return :: a -> Either a e > return x = Left x > exception :: e -> Either a e > exception x = Right x > extend :: (a -> Either a e) -> Either a e -> Either a e > extend f = join . (fmap f) > fmap :: (a -> b) -> Either a e -> Either b e > fmap f (Right e) = Right e > fmap f (Left x) = Left (f x) > join :: Either (Either a e) e -> Either a e > join (Right e) = Right e > join (Left (Right e)) = Right e > join (Left (Left x)) = Left x handle :: (a -> a -> Either a e) -> Either a e -> Either a e -> Either a e handle f x y = extend (\x' -> extend (\y' -> f x' y') y) x > add :: Int -> Int -> Either Int String > add x y = return (x + y) > sub :: Int -> Int -> Either Int String > sub x y = return (x - y) > div :: Int -> Int -> Either Int String > div x y = if y==0 then exception "Exception: Divide by zero" > else return (x `Prelude.div` y) > mul :: Int -> Int -> Either Int String > mul x y = return (x * y) ------------------------------------------------------------ Examples ------------------------------------------------------------ x = Left 3 > x = add 1 2 y = Left 17 > y = extend (\a -> add a 5) (mul 3 4) z = Right "Exception: Divide by zero" > z = div 1 0 w = Right "Exception: Divide by zero" > w = extend (\a -> add 1 a) (div 1 0) v = Left 42 > v = extend (\a -> extend (\b -> mul a b) (add 2 4)) (add 4 3)