0

I have the following code that compiles and runs fine. I tried to make it more compact by replacing case newEmployee of with case scanEmployee p of, but it didn't work. There's probably an easy way to remove newEmployee (and newTeam) from the code right?

module Main( main ) where
import Control.Monad.State
data Employee = EmployeeSW Int Int | EmployeeHW Int String deriving ( Show )
data Employee' = EmployeeSW' Int | EmployeeHW' String deriving ( Show )
scanTeam :: [Employee] -> State (Int,Int) (Either String [Employee'])
scanTeam [ ] = return (Right [])
scanTeam (p:ps) = do
 newEmployee <- scanEmployee p
 case newEmployee of
 Left errorMsg -> return (Left errorMsg)
 Right e -> do
 newTeam <- scanTeam ps
 case newTeam of
 Right n -> return (Right (e:n))
 Left errorMsg -> return (Left errorMsg)
scanEmployee :: Employee -> State (Int,Int) (Either String Employee')
-- actual code for scanEmployee omitted ...
asked Mar 3, 2019 at 19:26
1
  • 1
    Not really related to the question, but you might want to take a look at monad transformers, in particular ExceptT. It'd cut down the staircase of cases significantly. Commented Mar 3, 2019 at 19:37

2 Answers 2

3

You could use LambdaCase and be explicit with >>= instead of using do blocks. The result is not much shorter:

scanEmployee p >>= \case
 Left errorMsg -> return (Left errorMsg)
 Right e -> do ...
answered Mar 3, 2019 at 19:43
Sign up to request clarification or add additional context in comments.

1 Comment

I very often do this as well.
2

You can simplify your code a bit with mapM and sequence:

mapM scanEmployee :: [Employee] -> State (Int, Int) [Either String Employee')
sequence :: [ Either String a ] -> Either String [ a ]

(Note that these type signatures are simplifications and the actual types are more general. Specifically mapM and sequence work for any monad (not just Either String) and any traversable (not just ([])))

And write a simple solution:

scanTeam = fmap sequence . mapM scanEmployee
answered Mar 3, 2019 at 19:55

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.