Advertisement
hnefatl

Untitled

Mar 14th, 2018
72
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. module Demo where
  2.  
  3. import qualified Data.Set as S
  4.  
  5. import Control.Monad.State
  6. import Control.Monad.Except
  7.  
  8. type Input = String
  9. type ProcessedInput = String
  10. type Output = S.Set ProcessedInput
  11. data Error = InvalidFormat Input
  12.            | DuplicateInput ProcessedInput
  13.            deriving (Show)
  14.  
  15. processInput :: Input -> Maybe ProcessedInput
  16. processInput "" = Nothing
  17. processInput s = Just (tail s)
  18.  
  19. buildInputs :: [Input] -> Either Error Output
  20. buildInputs is = runExcept $ execStateT builder S.empty
  21.         where builder = sequence (map buildInputs' is)
  22.  
  23. buildInputs' :: Input -> StateT Output (Except Error) ()
  24. buildInputs' i = case processInput i of
  25.                    Nothing -> throwError (InvalidFormat i)
  26.                    Just p  -> ifM (gets $ S.member p) (throwError $ DuplicateInput p) (modify $ S.insert p)
  27.  
  28. buildInputs2 :: [Input] -> Either Error Output
  29. buildInputs2 is = runExcept $ execStateT (buildInputs2' is) S.empty
  30.  
  31. buildInputs2' :: [Input] -> StateT Output (Except Error) ()
  32. buildInputs2' [] = return ()
  33. buildInputs2' (i:is) = case processInput i of
  34.                        Nothing -> throwError (InvalidFormat i)
  35.                        Just p  -> do
  36.                                    ifM (gets $ S.member p) (throwError $ DuplicateInput p) (modify $ S.insert p)
  37.                                    buildInputs2' is
  38.  
  39. ifM :: Monad m => m Bool -> m a -> m a -> m a
  40. ifM cond t f = cond >>= \c -> if c then t else f
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement