Created
December 16, 2016 15:44
-
-
Save chrissound/66aff63401f46f59ce7730843a0b59ab to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import Control.Monad | |
| import Control.Monad.Trans | |
| import Control.Applicative | |
| data EitherMaybeT e a = EitherMaybeT {runEitherMaybe :: Either e (Maybe a)} | |
| instance Functor (EitherMaybeT e) where | |
| fmap f = EitherMaybeT . fmap (fmap f) . runEitherMaybe | |
| instance Applicative (EitherMaybeT e) where | |
| pure = return | |
| f <*> x = EitherMaybeT $ liftA2 (<*>) (runEitherMaybe f) (runEitherMaybe x) | |
| instance Monad (EitherMaybeT e) where | |
| return = (\x -> EitherMaybeT $ Right (Just x)) | |
| x >>= f = | |
| EitherMaybeT $ | |
| (case runEitherMaybe x of | |
| Right (Just z) -> runEitherMaybe $ f z | |
| Right (Nothing) -> Right Nothing | |
| Left z -> Left z | |
| ) | |
| is0 :: Int -> Maybe Int | |
| is0 x = case x of | |
| 0 -> Nothing | |
| x -> Just x | |
| isMultipleOf5 :: Int -> Either String Int | |
| isMultipleOf5 x = case mod x 5 of | |
| 0 -> Right x | |
| _ -> Left "Value was not multiple of 5" | |
| liftMaybe :: Maybe a -> EitherMaybeT e a | |
| liftMaybe = EitherMaybeT . Right | |
| liftEither :: Either e a -> EitherMaybeT e a | |
| liftEither x = case x of | |
| Right x' -> EitherMaybeT . Right . Just $ x' | |
| Left x' -> EitherMaybeT . Left $ x' | |
| if5EitherMaybe :: Int -> EitherMaybeT String Float | |
| if5EitherMaybe x = do | |
| x' <- liftMaybe $ is0 x | |
| x'' <- liftEither $ isMultipleOf5 x' | |
| return ((fromIntegral x'') / 5.0) | |
| if5EitherMaybeNotTransformed :: Int -> EitherMaybeT String Float | |
| if5EitherMaybeNotTransformed x = do | |
| case (is0 x) of | |
| Just x' -> case (isMultipleOf5 x) of | |
| Right x'' -> liftEither $ Right $ fromIntegral x'' / 5.0 | |
| Left x'' -> liftEither $ Left x'' | |
| Nothing -> liftMaybe $ Nothing | |
| main :: IO () | |
| main = do | |
| print "Transformer:" | |
| print . runEitherMaybe $ if5EitherMaybe 0 | |
| print . runEitherMaybe $ if5EitherMaybe 5 | |
| print . runEitherMaybe $ if5EitherMaybe 100 | |
| print . runEitherMaybe $ if5EitherMaybe 3 | |
| putStrLn "" | |
| print "Non transformer:" | |
| print . runEitherMaybe $ if5EitherMaybeNotTransformed 0 | |
| print . runEitherMaybe $ if5EitherMaybeNotTransformed 5 | |
| print . runEitherMaybe $ if5EitherMaybeNotTransformed 100 | |
| print . runEitherMaybe $ if5EitherMaybeNotTransformed 3 |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Output: