module Main where
{-
-- Instancias comentadas pois já estão definidas
instance Functor (Either a) where
fmap f (Left x) = Left x
fmap f (Right x) = Right (f x)
instance Applicative (Either a) where
pure x = Right x
(Left f) <*> _ = Left f
_ <*> (Left x) = Left x
(Right f) <*> (Right x) = Right (f x)
instance Monad (Either a) where
(Left x) >>= f = Left x
(Right x) >>= f = f x
-}
-- Exemplo
safeDiv :: (Show a, Eq a, Floating a) => a -> a -> Either String a
safeDiv a b
| b == 0 = Left ("Divisao por zero: " ++ show a ++ "/" ++ show b)
| otherwise = Right (a/b)
safeLog :: (Show a, Ord a, Eq a, Floating a) => a -> Either String a
safeLog x
| x <= 0 = Left ("Log invalido: " ++ show x)
| otherwise = Right (log x)
safeAdd :: Floating a => a -> a -> Either String a
safeAdd a b = Right (a+b)
safeExpr1, safeExpr2 :: Either String Double
safeExpr1 = do q <- safeDiv 10 (-2)
l <- safeLog q
safeAdd 2 q
safeExpr2 = do q <- safeDiv 10 0
safeAdd 2 q
main = do
print safeExpr1
print safeExpr2